Android四大组件之Service详解

2019-04-16  本文已影响0人  门心叼龙

1. service是什么?及其生命周期?

在前台不可见,但是承担大部分数据处理工作(劳模),它和Activity的地位是并列的,区别在于:Activity运行与前台,Service运行于后台,没有图形用户界面,通常他为其他的组件提供后台服务或监控其他组件的运行状态。
service的生命周期:

2. Service开启的方式?

startService: onCreate ->onStartCommand    
stopService:onDestroy
image.gif
bindService:onCreate->onBind
unbindService:onUnbind->onDetroy
image.gif

需求:既要保证服务长期在后台运行,又想去调用服务里面的方法
技巧:1.先开启服务 2.绑定服务

image image.gif


image image.gif

3. Service使用场景举例?

音乐播放器

4. 开机自启Service?

public class BootBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context,XXXclass);
        context.startService(service);
        //启动应用,参数为需要自动启动的应用的包名
        Intent intent = getPackageManager().getLaunchIntentForPackage(packageName);
        context.startActivity(intent );
    }
}
image.gif
<receiver android:name="BootBroadcastReceiver">
       <intent-filter>
           <action android:name="android.intent.action.BOOT_COMPLETED" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</receiver>
image.gif

4.3 添加权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 
image.gif

5. 什么是进程,什么是线程,进程分类?

进程就是正在进行中的程序,它是系统分配资源的基本单位,线程就是一次单一顺序的执行控制流, 一个进程里面可以有多个线程,一般情况下,一个应用程序会对应一个进程,关闭应用就是关闭了所有的界面,关闭所有的activity,应用程序的进程是不会关闭掉的,仍然在后台长期的运行,当系统内存不够用的时候会优先关闭空进程和后台进程。

采用一组组策略,帮助我们自动的管理进程,进程按照优先级分为不同的等级:

6.简述通过Binder调用服务流程?

7.创建绑定服务都有那几种方式?

8.通过扩展binder实现本地服务调用?

9.利用Messanger进行跨进程通信流程?

Messenger封装了Binder和Handler,有了Handler,Messenger就可以发送消息了,有了Binder,Messanger就可以远程通信了

结果:客户端拿到了服务端的信使【使用binder构造】,服务端拿到了客户端信使【使用消息携带】,然后就可以互发信息了
服务端:

public class MyService extends Service {
    private Messenger mServidceMessenger;// 服务端消息信使
    private Messenger mClientMessenger;// 客户端消息信使

    private Handler mServideHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 0:
                mClientMessenger = msg.replyTo;
                break;
            }
            super.handleMessage(msg);
        }
    };
    @Override
    public void onCreate() {    
        mServidceMessenger = new Messenger(mServideHandler);
    }
    @Override
    public IBinder onBind(Intent intent) {
        return mServidceMessenger.getBinder();
    }
}
image.gif

客户端:

pubblic class MainActivity extends Activity{
    private Messenger mServidceMessenger;// 服务端消息信使
    private Messenger mClientMessenger;// 客户端消息信使

    @Override
    public void onCreate(Bundle bundle){
        bindService(mService, new MyServiceConnection(), Context.BIND_AUTO_CREATE);
    }

    class MyServiceConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mServiceMessenger = new Messenger(iBinder);
                mClientMessenger = new Messenger(mClientHandler);
                Message msg = Message.obtain();
                msg.replyTo = mClientMessenger;
                msg.what = 0;
                mServiceMessenger.send(msg);
        }
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    }
    private Handler mClientHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };
} 
image.gif

10. AIDL架构分析?

image image.gif


image image.gif

11. AIDL跨进程服务调用工作原理?AIDL实现的步骤?

客户端和服务端通信协议解决了两个问题,服务端和客户端约定了方法参数列表顺序;约定了方法的ID标识
服务端:

客户端:

IMyService.aidl

package com.ryg.sayhi.aidl;
import com.ryg.sayhi.aidl.Student;
interface IMyService {
    List < Student > getStudent();
    void addStudent(in Student student);
}
image.gif
Student.aidl
package com.ryg.sayhi.aidl;
parcelable Student;
image.gif

Student.java

package com.ryg.sayhi.aidl;
public final class Student implements Parcelable {
    public int sno;
    public String name;
    public Student() {}
}
image.gif
public class MyService extends Service{
            private final IMyService.Stub mBinder = new IMyService.Stub() {
        @Override
        public List < Student > getStudent()throws RemoteException {}

        @Override
        public void addStudent(Student student)throws RemoteException {}

        //在这里可以做权限认证,return false意味着客户端的调用就会失败,比如下面,只允许包名为com.example.test的客户端通过,
        //其他apk将无法完成调用过程
        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            String packageName = null;
            String[]packages = MyService.this.getPackageManager().
                getPackagesForUid(getCallingUid());
            if (packages != null && packages.length > 0) {
                packageName = packages[0];
            }
            Log.d(TAG, "onTransact: " + packageName);
            if (!PACKAGE_SAYHI.equals("com.example.test")) {
                return false;
            }
            return super.onTransact(code, data, reply, flags);
        }
    };
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}
image.gif
 <service
android : name = "com.ryg.sayhi.MyService"
    android : process = ":remote"
    android : exported = "true" >
     < intent - filter >
     < category android : name = "android.intent.category.DEFAULT" /  >
     < action android : name = "com.ryg.sayhi.MyService" /  >
     <  / intent - filter >
     <  / service >
image.gif
import com.ryg.sayhi.aidl.IMyService;
import com.ryg.sayhi.aidl.Student;
public class MainActivity extends Activity implements OnClickListener {
private IMyService mIMyService;
private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mIMyService = null;
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mIMyService = IMyService.Stub.asInterface(service);
        }
        };
@ Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bindService(intentService, mServiceConnection, BIND_AUTO_CREATE);
}
}import com.ryg.sayhi.aidl.IMyService;
import com.ryg.sayhi.aidl.Student;
public class MainActivity extends Activity implements OnClickListener {
private IMyService mIMyService;
private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mIMyService = null;
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mIMyService = IMyService.Stub.asInterface(service);
        }
        };
@ Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bindService(intentService, mServiceConnection, BIND_AUTO_CREATE);
}
}
image.gif

12. AIDL 使用注意事项?

13.如何保证Service长期存活

总结:
1,6简单粗暴可以保证完全存活
4,5常用的方案
2,3比较轻量级
将Service设置为前台服务:(startForeground(int, Notification))

编码通过双服务实现服务长存?
https://www.cnblogs.com/zhujiabin/p/6073529.html

 <service android:name="ServiceOne" android:process=":remote">
            <intent-filter>
                <action android:name="com.example.servicedemo.ServiceOne"/>
            </intent-filter>
        </service>
        <service android:name="ServiceTwo" android:process=":remote">
            <intent-filter>
                <action android:name="com.example.servicedemo.ServiceTwo"/>
            </intent-filter>
</service>
image.gif
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent serviceOne = new Intent();
        serviceOne.setClass(MainActivity.this, ServiceOne.class);
        startService(serviceOne);

        Intent serviceTwo = new Intent();
        serviceTwo.setClass(MainActivity.this, ServiceTwo.class);
        startService(serviceTwo);
    }

    public static boolean isServiceWorked(Context context, String serviceName) {
        ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        ArrayList<RunningServiceInfo> runningService = (ArrayList<RunningServiceInfo>) myManager.getRunningServices(Integer.MAX_VALUE);
        for (int i = 0; i < runningService.size(); i++) {
            if (runningService.get(i).service.getClassName().toString().equals(serviceName)) {
                return true;
            }
        }
        return false;
    }
}
image.gif
public class ServiceOne extends Service {

    public final static String TAG = "com.example.servicedemo.ServiceOne";

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand");

        thread.start();
        return START_STICKY;
    }

    Thread thread = new Thread(new Runnable() {

        @Override
        public void run() {
            Timer timer = new Timer();
            TimerTask task = new TimerTask() {

                @Override
                public void run() {
                    Log.e(TAG, "ServiceOne Run: "+System.currentTimeMillis());
                    boolean b = MainActivity.isServiceWorked(ServiceOne.this, "com.example.servicedemo.ServiceTwo");
                    if(!b) {
                        Intent service = new Intent(ServiceOne.this, ServiceTwo.class);
                        startService(service);
                        Log.e(TAG, "Start ServiceTwo");
                    }
                }
            };
            timer.schedule(task, 0, 1000);
        }
    });

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

}
image.gif
public class ServiceTwo extends Service {

    public final static String TAG = "com.example.servicedemo.ServiceTwo";

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand");

        thread.start();
        return START_REDELIVER_INTENT;
    }

    Thread thread = new Thread(new Runnable() {

        @Override
        public void run() {
            Timer timer = new Timer();
            TimerTask task = new TimerTask() {

                @Override
                public void run() {
                    Log.e(TAG, "ServiceTwo Run: " + System.currentTimeMillis());
                    boolean b = MainActivity.isServiceWorked(ServiceTwo.this, "com.example.servicedemo.ServiceOne");
                    if(!b) {
                        Intent service = new Intent(ServiceTwo.this, ServiceOne.class);
                        startService(service);
                    }
                }
            };
            timer.schedule(task, 0, 1000);
        }
    });

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

}

image.gif
上一篇 下一篇

猜你喜欢

热点阅读