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
- Android中Service的意义及用法
- Android中WebView的意义及用法
- Android中SQLite的意义及用法
- Android中ContentProvider的意义及用法
- java 中super 的用法及意义
- Android中Bluetooth的意义和用法
- Android中Handler的意义和用法
- volatile的意义及用法
- explicit的用法及意义
- _T()的用法及意义
- _T()的用法及意义
- AIDL的意义及用法
- Android上几个常用硬件传感器的意义及用法
- php中$_SERVER变量的意义及用法说明
- JavaScript中apply与call的用法意义及区别
- PHP中双冒号::的用法及意义
- java 中super方法的用法及意义
- JavaScript中apply与call的用法意义及区别
- 参加蓝桥杯感受
- https://leetcode.com/problems/string-to-integer-atoi/
- shell脚本if case for while语句小例子
- 根文件系统的制作
- Light OJ Aladdin and the Flying Carpet(约数个数)
- Android中Service的意义及用法
- 第一次写——ACM
- 【Linux】在Ubuntu中安装Eclipse与Helloworld
- Material Design Style Widget(二)──MaterialRadioButton(续)
- Java实现重构二叉树
- LeetCode Maximal Rectangle
- 第六周上机实践项目1——深复制体验(1)
- Android 程序框架设计
- Redis学习备忘 Jedis