深入理解android service的基本知识

    xiaoxiao2021-03-25  123

    参考自: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();//辅助Intent mIntent.setAction("com.android.ForegroundService"); final Intent serviceIntent=new Intent(getExplicitIntent(this,mIntent)); startService(serviceIntent); 问题,如果Service在AndroidManifest中设置process属性,调用startService或者BindService;其中onCreate(), onStartCommand() 不会被调用。

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

    六,

    转载请注明原文地址: https://ju.6miu.com/read-6675.html

    最新回复(0)