1、通过startservice方法启动一个服务,service不能自己启动自己。若在一个服务中启动一个activity则,必须是申明一个全新的activity任务TASK。通过startservice方法启动的服务不会随着启动组件的消亡而消亡,而是一直运行着。
Service生命周期 onCreate()-------->onStartCommand()----------->onDestroy()
startService()启动一个服务后,若在该服务做耗时操作且没有写线程,则会导致主线程阻塞!
服务启动运行后会一直运行onStartCommand()方法。
2、用bindService启动一个服务,该服务和activity是绑定在一起的:启动时,先调用onCreate()------>onBind()--------->onServiceConnected(),启动服务的组件消亡,服务也就消亡了。
3、AIDL服务调用方式
demo下载地址:http://download.csdn.net/detail/u014600432/8175529
1)服务端代码:
首先定义一个接口描述语言的接口:
package com.example.service; interface DataService{ double getData(String arg); }
/** *Version: *author:YangQuanqing *Data: */ package com.example.android_aidl_service; import com.example.service.DataService; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; /** * @author YangQuanqing yqq * */ public class MyService extends Service { @Override public IBinder onBind(Intent arg0) { <span style="color:#ff0000;">//返回binder由didl文件生成</span> return binder; } //定义给客户端调用的方法 (aidl文件) Binder binder=new <span style="color:#ff0000;">DataService.Stub()</span> { @Override public double getData(String arg) throws RemoteException { if(arg=="a"){ return 1; } if(arg=="b"){ return 2; } return 0; } }; }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android_aidl_service" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.android_aidl_service.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="com.example.android_aidl_service.MyService" > <intent-filter> <!-- 意图过滤器要把aidl包名加类名 --> <action android:name="com.example.service.DataService"/> </intent-filter> </service> </application> </manifest>
把aidl文件包拷贝到客户端,客户端代码如下:
package com.example.android_aidl_client; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import com.example.service.DataService; public class MainActivity extends Activity { private Button btn1,btn2; //定义一个AIDL实例 private DataService dataService; private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn1=(Button)this.findViewById(R.id.button1); btn2=(Button)this.findViewById(R.id.button2); tv=(TextView)this.findViewById(R.id.textView1); //绑定服务 btn1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(DataService.class.getName()); //启动服务 bindService(intent, conn, BIND_AUTO_CREATE); } }); //调用服务的方法 btn2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { int result=(int) dataService.getData("a"); tv.setText(result+""); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } //客户端与服务交互 private ServiceConnection conn=new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { //传入service dataService=DataService.Stub.asInterface(service); } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
访问界面代码:
package com.example.android_service_binder; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import com.example.android_service_binder.MyService.LocalBinder; public class MainActivity extends Activity { //销毁绑定 @Override protected void onStop() { super.onStop(); if(flag) { //解除绑定 unbindService(serviceConnection); flag=false; } } //绑定Service @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); /*Intent intent=new Intent(MainActivity.this,MyService.class); //启动service bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);*/ } private Button btnBinder=null; private Button btnCall=null; private TextView tv=null; private MyService myService;//service实例 private boolean flag=false;//默认不绑定 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnBinder=(Button)this.findViewById(R.id.button1); btnCall=(Button)this.findViewById(R.id.button2); tv=(TextView)this.findViewById(R.id.textView1); btnBinder.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(MainActivity.this,MyService.class); //启动service bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } }); //调用service方法 btnCall.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //处于绑定状态 if(flag) { int result=myService.getRandom(); tv.setText("<<<<<"+result); } } }); } private ServiceConnection serviceConnection= new ServiceConnection(){ //连接 @Override public void onServiceConnected(ComponentName arg0, IBinder iBinder) { //获得服务的The IBinder of the Service's communication channel, which you can now make calls on. LocalBinder binder=(LocalBinder) iBinder; //获得服务 myService=binder.getService(); flag=true; } //不连接 @Override public void onServiceDisconnected(ComponentName arg0) { flag=false; } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
/** *Version: *author:YangQuanqing *Data: */ package com.example.android_service_binder; import java.util.Random; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; /** * @author YangQuanqing yqq * */ public class MyService extends Service { private final LocalBinder lb=new LocalBinder(); private final Random num=new Random(); @Override public IBinder onBind(Intent arg0) { // 返回本地Binder的子类实例 return lb; } //定义一个本地Binder类继承Binder public class LocalBinder extends Binder{ //获得Servie子类当前实例给客户端 public MyService getService(){ return MyService.this; } } public int getRandom(){ return num.nextInt(98); } }
demo下载地址:http://download.csdn.net/detail/u014600432/8175633
5、IntentService
本质是开启一个线程来完成耗时操作。
IntentService生命周期:
onCreate()------->onStartCommand()--------->onHandleIntent()--------->onDestroy()
/** *Version: *author:YangQuanqing *Data: */ package com.example.android_intentservice; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import android.app.IntentService; import android.content.Intent; import android.os.Environment; import android.widget.Toast; /** * @author YangQuanqing 不需要开启线程(看源码知道是自己封装了开启线程),不需要关闭服务,自己关闭,单线程下载数据 * * 一定要记得实例化!!! */ public class DownLoadService extends IntentService { @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); } public DownLoadService() { super("DownLoadService"); } // 只需复写如下方法 // 在该方法中执行操作 @Override protected void onHandleIntent(Intent intent) { // 获得提取网络资源的实例 HttpClient httpClient = new DefaultHttpClient(); // 设置请求方式 HttpPost httpPost = new HttpPost(intent.getStringExtra("url")); // 设置存储路径 File file = new File(Environment.getExternalStorageDirectory(), "IntentService.gif"); // 定义输出流用于写 FileOutputStream fileOutputStream = null; byte[] data = null;// 网络数据 try { // 执行请求获得响应 HttpResponse httpResponse = httpClient.execute(httpPost); // 判断响应状态码 if (httpResponse.getStatusLine().getStatusCode() == 200) { // 获得响应实体 HttpEntity httpEntity = httpResponse.getEntity(); // 获得网络数据 data = EntityUtils.toByteArray(httpEntity); // 判断SD卡是否可用 if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { // 写入SD卡 fileOutputStream=new FileOutputStream(file); fileOutputStream.write(data, 0, data.length); //Toast.makeText( DownLoadService.this,"下载完成", Toast.LENGTH_LONG).show(); Toast.makeText( getApplicationContext(),"下载完成", Toast.LENGTH_LONG).show(); } } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
package com.example.android_intentservice; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { private Button btn_intent=null; private String url="http://www.baidu.com/img/bdlogo.gif"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_intent=(Button)this.findViewById(R.id.button1); btn_intent.setOnClickListener(new OnClickListener(){ @Override public void onClick(View arg0) { Intent intent=new Intent(MainActivity.this,DownLoadService.class); intent.putExtra("url", url); startService(intent); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }