Android中Service的意义及用法

来源:互联网 发布:琉璃神社换的域名2017 编辑:程序博客网 时间:2024/06/05 23:21

1、下面介绍Service和AsyncTask的用法和比较。

Service没有界面,用于执行一个需要在后台长期运行的任务。AsyncTask用于执行短时间的异步任务,并跟UI线程交互,用于替代Thread和Handler。

1) MainActivity.java

public class MainActivity extends Activity {private static final String TAG = MainActivity.class.getSimpleName();/**便于多次、多地调用,生命周期伴随Activity*/Intent intent;@Overrideprotected void onCreate(Bundle savedInstanceState) {Log.i(TAG, "onCreate");super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//mAsyncTask.execute("http://www.qinuli.com:83/picture/thumb.jpg", "http://www.qinuli.com:83/picture/hand_in_hand.jpg");intent = new Intent(this, MyService.class);}protected void onDestroy() {Log.d(TAG, "onDestroy");super.onDestroy();};/** * 定义一个AsyncTask的子类;实例化并在UI线程调用其execute方法 * <li>3个参数:Params、Progress、Result * <li>4 steps:onPreExecute->doInBackground->onProgressUpdate->onPostExecute * <li>功能:用于后台执行前台显示的任务 * <li>意义:代替或封装Thread和Handler,方便后台线程和UI线程交互 */AsyncTask<String, Integer, CharSequence> mAsyncTask = new AsyncTask<String, Integer, CharSequence>() {@Overrideprotected void onPreExecute() {Log.d(TAG, "onPreExecute");};@Overrideprotected CharSequence doInBackground(String... params) {//perform a computation on a background threadfor(int i=0;i<params.length;i++){publishProgress(Integer.valueOf(i));}return "加油!";}@Overrideprotected void onProgressUpdate(Integer... values) {Log.d(TAG, "onProgressUpdate-"+values[0]);};@Overrideprotected void onPostExecute(CharSequence result) {Log.d(TAG, "onPostExecute-"+result);};};private ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {Log.d(TAG, "onServiceDisconnected-"+name.getClassName());}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//由bindService触发,在onBind之后MyService myService = ((MyBinder)service).getService();Log.d(TAG, "onServiceConnected-"+name.getClassName()+"-"+myService.name);}};public void onClick(View v){switch (v.getId()) {case R.id.btn_startService://调用Service的空参构造startService(intent);break;case R.id.btn_stopService:stopService(intent);break;case R.id.btn_bindService:bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);break;case R.id.btn_unbindService:unbindService(mServiceConnection);}}}
2) activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    xmlns:android="http://schemas.android.com/apk/res/android">    <Button         android:id="@+id/btn_startService"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="onClick"        android:text="startService"/>    <Button         android:id="@+id/btn_stopService"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="onClick"        android:text="stopService"/>    <Button         android:id="@+id/btn_bindService"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="onClick"        android:text="bindService"/>    <Button         android:id="@+id/btn_unbindService"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="onClick"        android:text="unbindService"/></LinearLayout>
3) MyService.java,讲解startService和bindService的原理
/** * <li>Service的意义:perform a longer running operation * <li>Service和AsyncTask的区别:Service运行在主线程,不会结束 */public class MyService extends Service {private static final String TAG = MyService.class.getSimpleName();private MyBinder myBinder = new MyBinder();public String name = "ShiXin";public MyService(){super();Log.d(TAG, "MyService");}/**继承Binder类,Binder类实现IBinder接口。实例化该类供onBind使用*/public class MyBinder extends Binder{/**返回Service的实例,进而调用其方法和属性,实现一些数据通信和功能操作*/public MyService getService(){return MyService.this;}}@Overridepublic IBinder onBind(Intent intent) {Log.d(TAG, "onBind");//由bindService触发return myBinder;}@Overridepublic boolean onUnbind(Intent intent) {Log.d(TAG, "onUnbind");return super.onUnbind(intent);}@Overridepublic void onCreate() {Log.d(TAG, "onCreate");//重新实例化新的Servicesuper.onCreate();}public void onDestroy() {Log.d(TAG, "onDestroy");super.onDestroy();};@Overridepublic void onStart(Intent intent, int startId) {//deprecated 被onStartCommand代替super.onStart(intent, startId);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//每次startService都会触发,bindService不会触发//startId:unique integer token,标记每次startService,Service创建后从1开始计数//START_STICKY_COMPATIBILITY 0;Service.START_STICKY 1stopSelfResult(3);//onStartCommand执行3次int state = super.onStartCommand(intent, flags, startId);Log.d(TAG, "onStartCommand-"+intent.getComponent().getClassName()+"-"+flags+"-"+startId+"-"+state);return state;//1}}
4) MyIntentService.java,IntentService用于在后台线程执行异步任务,执行完Service自动destroy
/** * handle asynchronous requests */public class MyIntentService extends IntentService {private static final String TAG = MyIntentService.class.getSimpleName();public MyIntentService() {//name worker threadsuper("worker thread");}@Overrideprotected void onHandleIntent(Intent intent) {//代替onStartCommand;执行完调用stopSelf()Log.d(TAG, Thread.currentThread().getName()+"-onHandleIntent");}@Overridepublic void onCreate() {Log.d(TAG, "onCreate");super.onCreate();}@Overridepublic void onDestroy() {Log.d(TAG, "onDestroy");super.onDestroy();}}
5) AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.qinuli.testproject"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="19" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity android:name="com.qinuli.testproject.MainActivity">            <intent-filter >                <action android:name="android.intent.action.MAIN"/>                <category android:name="android.intent.category.LAUNCHER"/>            </intent-filter>        </activity>        <service android:name="com.qinuli.testproject.MyService"></service>        <service android:name="com.qinuli.testproject.MyIntentService"></service>    </application></manifest>

2、如何让服务永久运行

本示例介绍了TIME_TICK和BOOT_COMPLETED广播的用法

public class MainActivity extends Activity {private static final String TAG = MainActivity.class.getSimpleName();@Overrideprotected void onCreate(Bundle savedInstanceState) {Log.d(TAG, "onCreate");super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overrideprotected void onDestroy() {Log.d(TAG, "onDestroy");super.onDestroy();}public void onClick(View v){switch(v.getId()){case R.id.btn_killProcess:Process.killProcess(Process.myPid());}}}
MyService.java

public class MyService extends Service {private static final String TAG = MyService.class.getSimpleName();private MyBinder myBinder = new MyBinder();public class MyBinder extends Binder{public MyService getService(){return MyService.this;}}@Overridepublic IBinder onBind(Intent intent) {return myBinder;}@Overridepublic void onCreate() {Log.d(TAG, "onCreate");super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d(TAG, "onStartCommand");//进程被杀死,服务会重建return Service.START_STICKY;}@Overridepublic void onDestroy() {Log.d(TAG, "onDestroy");super.onDestroy();}}
MyApplication.java
public class MyApplication extends Application {private static final String TAG = MyApplication.class.getSimpleName();MyService myService;Intent intent;@Overridepublic void onCreate() {Log.d(TAG, "onCreate");super.onCreate();intent = new Intent(this, MyService.class);startService(intent);bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);registerReceiver(new TimeTickReceiver(), new IntentFilter(Intent.ACTION_TIME_TICK));}@Overridepublic void onTerminate() {Log.d(TAG, "onTerminate");super.onTerminate();stopService(intent);//禁用一个manifest receiver,可禁用清单文件里注册的四大组件ComponentName componentName = new ComponentName(this, BootCompletedReceiver.class);PackageManager pm = getPackageManager();pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);}private ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {myService = null;}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {Log.d(TAG, "onServiceConnected");myService = ((MyBinder)service).getService();}};}
BootCompleteReceiver.java
public class BootCompletedReceiver extends BroadcastReceiver {private static final String TAG = BootCompletedReceiver.class.getSimpleName();public BootCompletedReceiver(){super();Log.d(TAG, "BootCompletedReceiver");}public void onReceive(Context context, Intent intent) {String action = intent.getAction();Log.d(TAG, action);if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {//清单文件注册,开机可收到广播boolean isServiceRunning = false;ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);for(RunningServiceInfo runningServiceInfo:activityManager.getRunningServices(Integer.MAX_VALUE)){if(MyService.class.getName().equals(runningServiceInfo.service.getClassName())){isServiceRunning = true;}}if(!isServiceRunning){ComponentName comp = new ComponentName(context.getPackageName(), MyService.class.getName());context.startService(new Intent().setComponent(comp));}}else if(ConnectivityManager.CONNECTIVITY_ACTION.equals(action)){//在清单文件注册,退出APP或杀死进程依然能收到广播,但清掉内存就收不到了ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo networkInfo = cm.getActiveNetworkInfo();if(networkInfo!=null)Log.d(TAG, "networkstate:"+networkInfo.isConnectedOrConnecting()+"-"+(networkInfo.getType()==ConnectivityManager.TYPE_MOBILE));}}}
TimeTickReceiver.java
public class TimeTickReceiver extends BroadcastReceiver {private static final String TAG = TimeTickReceiver.class.getSimpleName();public TimeTickReceiver(){super();Log.d(TAG, "TimeTickReceiver");}@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();Log.d(TAG, action);if (Intent.ACTION_TIME_TICK.equals(action)) {boolean isServiceRunning = false;//拿到所有正在运行的服务ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);for(RunningServiceInfo runningServiceInfo:activityManager.getRunningServices(Integer.MAX_VALUE)){if(MyService.class.getName().equals(runningServiceInfo.service.getClassName())){isServiceRunning = true;}}Log.d(TAG, "isServiceRunning="+isServiceRunning);if(!isServiceRunning){ComponentName comp = new ComponentName(context.getPackageName(), MyService.class.getName());context.startService(new Intent().setComponent(comp));}}}}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.qinuli.servicetest"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>        <application        android:name="com.qinuli.servicetest.MyApplication"        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity android:name="com.qinuli.servicetest.MainActivity">            <intent-filter >                <action android:name="android.intent.action.MAIN"/>                <category android:name="android.intent.category.LAUNCHER"/>            </intent-filter>        </activity>        <service android:name="com.qinuli.servicetest.MyService"            android:enabled="true"            android:exported="false"/>        <receiver            android:name="com.qinuli.servicetest.BootCompletedReceiver"            android:permission="android.permission.RECEIVE_BOOT_COMPLETED"            android:enabled="true" >            <intent-filter>                <action android:name="android.intent.action.BOOT_COMPLETED" />                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>            </intent-filter>        </receiver>    </application></manifest>


0 0
原创粉丝点击