深入理解android service的基本知识

来源:互联网 发布:阿里云cdn隐藏ip 编辑:程序博客网 时间:2024/04/29 22:54

参考自:http://blog.csdn.net/guolin_blog/article/details/11952435

http://blog.csdn.net/javazejian/article/details/52709857



一,Service的基本用法:

1,创建一个Service:MyService extends Service,并重写onCreate(), onStartCommand()和onDestroy()

-------------- onStart() 已经不使用。


2,启动和停止Service:

 Intent startIntent = new Intent(this, MyService.class); startService(startIntent);

3, 需要在AndroidManifest中生命该Service 

 <service            android:name=".MyService"            android:enabled="true"            android:exported="true"></service>


二,Service 和 Activity通信:Service的绑定:onBind()  bindService();

1) 增加新类MyBinder类继承自Binder类:

    class MyBinder extends Binder {        public void startDownload() {            Log.d(TAG, "startDownload() executed");        }    }

2)  并在onBind()时返回该MyBinder实例:

 private MyBinder mBinder = new MyBinder();    @Override    public IBinder onBind(Intent intent) {        Log.d("MyService", "====== onBind ============");        return mBinder;    }

3) 定义ServiceConnection: 用于在Activity和Service之间连接上之后的处理动作:connection

 private MyService.MyBinder myBinder;    private ServiceConnection connection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName componentName, IBinder service) {            myBinder = (MyService.MyBinder) service;            myBinder.startDownload();            Log.d("ServiceConnection", " ======== onServiceConnected ============ ");        }        @Override        public void onServiceDisconnected(ComponentName componentName) {            Log.d("ServiceConnection", " ======== onServiceDisConnected ============ ");        }    };

4) 在Activity中绑定该ServiceConnection:

Intent bindIntent = new Intent(this, MyService.class);bindService(bindIntent, connection, BIND_AUTO_CREATE);

通过上述动作,就可以把Activity和Service绑定,并把任务交到Service去处理。


参考,标准的Service实现模型:

@Override  public int onStartCommand(Intent intent, int flags, int startId) {      new Thread(new Runnable() {          @Override          public void run() {              // 开始执行后台任务          }      }).start();      return super.onStartCommand(intent, flags, startId);  }    class MyBinder extends Binder {        public void startDownload() {          new Thread(new Runnable() {              @Override              public void run() {                  // 执行具体的下载任务              }          }).start();      }    }  


三,Service的生命周期:

startService() 和 BindService() 均可以启动一个Service,两者的生命周期如下:

需要注意的是Service的销毁,当同时使用StartService()和bindService() 一起调用Service的,如果Service还被绑定,直接调用StopService()是无法销毁该Service的


四,创建前台Service:

创建前台Service的目的:1,提高后台运行Service的优先级;2,避免系统因内存不足而kill掉该Service。

前台Service和普通Service的最大的区别在于:它会一直有一个正在运行的图标显示在状态栏。

   Intent notificationIntent = new Intent(this, MainActivity.class);        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,                notificationIntent, 0);        Notification.Builder builder = new Notification.Builder(this)                .setContentIntent(pendingIntent)                .setSmallIcon(R.mipmap.ic_launcher)                .setContentTitle("这是通知的标题");        Notification notification = builder.build();        startForeground(1, notification);   //调到前台


五,Android 5.0以上的隐式启动问题:

在Android 5.0之后google出于安全的角度禁止了隐式声明Intent来启动Service。

解决办法:

* 设置Action和packageName:

final Intent serviceIntent=new Intent(); serviceIntent.setAction("com.android.ForegroundService");serviceIntent.setPackage(getPackageName());//设置应用的包名startService(serviceIntent);


* 将隐式启动转换为显示启动:

public static Intent getExplicitIntent(Context context, Intent implicitIntent) {    // Retrieve all services that can match the given intent     PackageManager pm = context.getPackageManager();     List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);     // Make sure only one match was found     if (resolveInfo == null || resolveInfo.size() != 1) {         return null;     }     // Get component info and create ComponentName     ResolveInfo serviceInfo = resolveInfo.get(0);     String packageName = serviceInfo.serviceInfo.packageName;     String className = serviceInfo.serviceInfo.name;     ComponentName component = new ComponentName(packageName, className);     // Create a new intent. Use the old one for extras and such reuse     Intent explicitIntent = new Intent(implicitIntent);     // Set the component to be explicit     explicitIntent.setComponent(component);     return explicitIntent;    }


使用如下方式调用:

Intent mIntent=new Intent();//辅助IntentmIntent.setAction("com.android.ForegroundService");final Intent serviceIntent=new Intent(getExplicitIntent(this,mIntent));startService(serviceIntent);


问题,如果Service在AndroidManifest中设置process属性,调用startService或者BindService;其中onCreate(), onStartCommand() 不会被调用。

需要通过调用AIDL相应的接口,实现所需要的远程调用。



六,



0 0
原创粉丝点击