安卓四大组件之Service

Service能否执行耗时操作

Service和Activity一样都是运行在主线程的,配置下android的Process属性可以让service在另外的进程中执行

service生命周期

service有三种启动模式,绑定模式,非绑定模式和混合模式

非绑定模式:

  • startService():onCreate(); onStartCommand();
  • stopService():onDestory();

绑定模式:

  • bindService(): onCreate(); onBind();
  • unbindService(): onUnbind(); onDestroy();

IntentService介绍

  • 首先是Service的子类,但它会创建独立的worker线程在onHandleIntent()方法中处理耗时操作
  • 请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service;
  • 为 Service 的 onBind()提供默认实现,返回 null
  • 为 Service 的 onStartCommand 提供默认实现,将请求 Intent 添加到队列中

MainActivity.java

public void click(View view) {
    Intent intent = new Intent(this, MyIntentService.class); 
    intent.putExtra("start", "MyIntentService"); 
    startService(intent);
}

MyIntentService.java

public class MyIntentService extends IntentService {

    private String ex = "";
    private Handler mHandler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            Toast.makeText(getApplicationContext(), "-e: "+ex, Toast.LENGTH_LONG).show();
        };
    };
    
    // 注意:这里必须要有无参构造函数
    // RuntimeException: MyIntentService has no zero argment constructor
    public MyIntentService() {
        super("MyIntentService");
    }

    // 为 Service 的 onStartCommand 提供默认实现,将请求 Intent 添加到队列中
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ex = intent.getStringExtra("start");
        return super.onStartCommand(intent, flags, startId);
    }

    // 为 Service 的 onBind()提供默认实现,返回 null
    @Override
    public IBinder onBind(Intent intent) {
        return super.onBind(intent);
    }
    
    // 会创建独立的 worker 线程来处理 onHandleIntent()方法实现的代码,处理耗时操作
    // 请求处理完成后,IntentService 会自动停止,无需调用 stopSelf()方法停止 Service;
    @Override
    protected void onHandleIntent(Intent intent) {
        try { 
            Thread.sleep(1000);
        } catch (InterruptedException e) { 
            e.printStackTrace();
        } 
        
        mHandler.sendEmptyMessage(0);
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

Activity,Intent,Service是什么关系

Activity和Service是Context的子类,是ContextWrapper的子类。它们之间可以通过Intent传递数据。

Service的onStartCommand()有几种返回值?代表什么?

有四种返回值。

START_STICKY: 服务被杀死会重启,但是Intent对象没有保存

START_NOT_STICKY:执行完onStartCommand()后,服务被杀死不会重启

START_REDELIVER_INTENT:服务被杀死会重启,并传入Intent

START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但服务被杀死不一定能重启

Service的onRebind(Intent)在什么情况下会执行?

在onUnbind()方法返回true的时候会执行,否则不执行

Activity调用Service的方法有哪些方式

一:bindService绑定服务,传入ServiceConnection接口的实现类,在该接口的onServiceConnected()回调中获取Binder子类

Intent intent = new Intent(this, BaoService.class);
MyConnection conn = new MyConnection();
bindService(intent, conn, BIND_AUTO_CREATE);
class MyConnection implements ServiceConnection{
    
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        zms = (PublicBusiness) service;
    }
    
    @Override
    public void onServiceDisconnected(ComponentName name) {
        // TODO Auto-generated method stub
    }
}
    
zms.qianXian();
    
//----------------------------------------
    
public class BaoService extends Service {
    
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("bind");
        return new ZhongMiShu();
    }
    
    class ZhongMiShu extends Binder implements PublicBusiness{
        @Override
        public void qianXian(){
            BaoService.this.banZheng();
        }
    }
    
    public void banZheng() {
        System.out.println("钱一收到,证就办好");
    }
}
    
//--------------------------------------
    
public interface PublicBusiness {
    void qianXian();
}

二:Messenger方式:onBind()方法返回Messenger对象

public class MainActivity extends AppCompatActivity {
    
    Messenger mService = null;
    boolean mBound;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
    @Override
    protected void onStart() {
        super.onStart();
        bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE);
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        if (mBound){
            unbindService(mConnection);
            mBound = false;
        }
    }
    
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = new Messenger(service);
            mBound = true;
        }
    
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mService = null;
            mBound = false;
        }
    };
    
    public void sayHello(View view){
        if (!mBound) return;
    
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
        try {
            mService.send(msg);
        }catch (RemoteException e){
            e.printStackTrace();
        }
    }
    
}
public class MessengerService extends Service {
    
    static final int MSG_SAY_HELLO = 1;
    
    class IncomingHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MSG_SAY_HELLO:
                    Toast.makeText(getApplicationContext(),"hello",Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }
    
    final Messenger mMessenger = new Messenger(new IncomingHandler());
    
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(getApplicationContext(),"binding",Toast.LENGTH_SHORT).show();
        return mMessenger.getBinder();
    }
    
}

三:AIDL 进程间通讯

aidl 是Android interface definition Language 的英文缩写,意思Android 接口定义语言。aidl 可以帮助我们发布以及调用远程服务,实现跨进程通信。

  • 将对应的aidl后缀文件放到src目录下会自动生成对应的接口类
  • 将对应的aidl文件拷贝到相同路径的包下
  • 通过bindService(Intent, ServiceConnection, int); 实现ServiceConnection接口的onServiceConnected方法获取代理对象IBinder
  • 通过Stub.asInterface(IBinder);获取得到aidl生成的接口类,即可调用跨进程方法

你可能感兴趣的:(安卓四大组件之Service)