当前位置:网站首页>Service learning notes 02- actual combat startservice and bindservice

Service learning notes 02- actual combat startservice and bindservice

2022-06-11 17:31:00 Shuangmu green orange

There are two ways to start a service

Most common startup Service The two ways of doing this are startService and bindService, The main difference between them can be referred to startService And bindService The difference between

Start the service

By binding the service, you can get the corresponding information on the client Service References to , So as to complete and Service Interaction . The main process is shown in the figure below :

  • First , In succession Service Create a new custom service that inherits from IBinder The inner class of , stay IBinder In order to get myService References to
  • In service onBinder() method Service Medium IBinder Object injection ( This method will be in The binding service is called when it succeeds , The client can obtain IBinder object , And then to get Service References to )
  • Declare a on the client side ServiceConnection object , stay ServiceConnection Object's onServiceContected() ( This method is called when the binding service succeeds ) You can get IBinder object
  • By getting IBinder Object acquisition Service quote , Can get Service Data and methods in
    binderService Method to start the service process

Code combat

First , Let's define a TestService, increase myBinder The inner class of , Through a public Class return TestService object , Then rewrite onBind Methods will Binder Class returns to the client , This is a necessary step , So that the client can go through bind To get our Service

public class TestService extends Service {
    
    private static final String TAG = "TestService";
    private static final Random generator = new Random();

    // adopt binder Implementation calls client And Service Communication between 
    private MyBinder binder;

    // Think of your own Service  Support bindService Mode of starting , Must be in Service Of OnBind Method returns a IBinder Instance of type 
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    
        Log.i(TAG, "TestService -> onBind,Thread:" + Thread.currentThread().getName());
        return binder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
    
        Log.i(TAG, "TestService -> onUnbind,Thread:" + intent.getStringExtra("from"));
        return false;
    }

    public class MyBinder extends Binder {
    
        public TestService getService() {
    
            return TestService.this;
        }
    }

    @Override
    public void onCreate() {
    
        Log.i(TAG, "TestService -> onCreate,Thread:" + Thread.currentThread().getName());
        super.onCreate();
        binder=new MyBinder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
        Log.i(TAG, "TestService -> onStartCommand,StartId: " + startId + "Thread:" + Thread.currentThread().getName());
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
    
        Log.i(TAG, "TestService -> onDestroy,Thread:" + Thread.currentThread().getName());
        super.onDestroy();
    }

    //Service  Exposed for client Public method called 
    public int getRandomNumber() {
    
        return generator.nextInt();
    }
}

And then in Activity Through bindService To start up Service

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
    private static final String TAG="MainActivity";

    private TestService service=null;

    private boolean isBound=false;

    private ServiceConnection connection=new ServiceConnection() {
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
    
            isBound=true;
            TestService.MyBinder myBinder=(TestService.MyBinder)binder;
            service= myBinder.getService();
            Log.i(TAG,"MainActivity onServiceConnected");
            int num=service.getRandomNumber();
            Log.i(TAG,"MainActivity  Call in TestService Of getRandomNumber Method , result :"+num);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
    
            isBound=false;
            Log.i(TAG,"MainActivity onServiceDisconnected");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i(TAG,"MainActivity -> onCreate,Thread:"+Thread.currentThread().getName());

        Button bindServiceButton=(Button)findViewById(R.id.btnBindService);
        bindServiceButton.setOnClickListener(this);
    }
    
    @Override
    public void onClick(View v) {
    
        Log.i(TAG,"onClick has into");
        if(v.getId()==R.id.btnBindService){
    
            Intent intent=new Intent(this,TestService.class);
            intent.putExtra("from","ActivityA");
            Log.i(TAG,"MainActivity  perform  bindService");
            bindService(intent,connection,BIND_AUTO_CREATE);
        }else if(v.getId()==R.id.btnUnBindService){
    
            if(isBound){
    
                Log.i(TAG,"MainActivity  perform  unBindService");
                unbindService(connection);
            }
        }
    }
}    

stay MainActivity First, create an implementation ServiceConnection Member variables of connection, It mainly needs to be rewritten onServiceConnected Method , Create... In it IBinder object , And get Serivice object

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
    private static final String TAG="MainActivity";
    private TestService service=null;
    private boolean isBound=false;

    private ServiceConnection connection=new ServiceConnection() {
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
    
            isBound=true;
            TestService.MyBinder myBinder=(TestService.MyBinder)binder;
            service= myBinder.getService();
            Log.i(TAG,"MainActivity onServiceConnected");
            int num=service.getRandomNumber();
            Log.i(TAG,"MainActivity  Call in TestService Of getRandomNumber Method , result :"+num);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
    
            isBound=false;
            Log.i(TAG,"MainActivity onServiceDisconnected");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i(TAG,"MainActivity -> onCreate,Thread:"+Thread.currentThread().getName());

        Button bindServiceButton=(Button)findViewById(R.id.btnBindService);
        bindServiceButton.setOnClickListener(this);
        Button unBindServiceButton=(Button)findViewById(R.id.btnUnBindService);
        unBindServiceButton.setOnClickListener(this);
        Button startActivityButton=(Button)findViewById(R.id.btnStartActivity);
        startActivityButton.setOnClickListener(this);
        Button coastRandomNumButton=(Button)findViewById(R.id.btnCoastRandomNum);
        coastRandomNumButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
    
        Log.i(TAG,"onClick has into");
        if(v.getId()==R.id.btnBindService){
    
            Intent intent=new Intent(this,TestService.class);
            intent.putExtra("from","ActivityA");
            Log.i(TAG,"MainActivity  perform  bindService");
            bindService(intent,connection,BIND_AUTO_CREATE);
        }else if(v.getId()==R.id.btnUnBindService){
    
            if(isBound){
    
                Log.i(TAG,"MainActivity  perform  unBindService");
                unbindService(connection);
            }
        }else if(v.getId()==R.id.btnStartActivity){
    
            Intent intent=new Intent(this,ActivityB.class);
            Log.i(TAG,"MainActivity  start-up ActivityB");
            startActivity(intent);
        }else if(v.getId()==R.id.btnFinish){
    
            Log.i(TAG,"MainActivity  perform  finish");
            this.finish();
        }else if(v.getId()==R.id.btnCoastRandomNum){
    
            Log.i(TAG,"MainActivity  perform  coastRandom");
            Log.i(TAG,"random num :"+service.getRandomNumber());
        }
    }

    @Override
    protected void onDestroy() {
    
        Log.i(TAG,"MainActivity -> onDestroy");
        super.onDestroy();
    }
}
  • problem 1: In the same Activity Re execution bindService How will the method ?
    Re execution ServiceConnection Of onServiceConnected Method
  • problem 2: bindService perhaps unBindService What happens if you don't appear in pairs ?
    After verification : repeat bindService Method only executes once Service Of onBind and onCreate Method ,bindService A singleton mechanism is made internally , But if you do it many times unBindService Methods throw exceptions directly java.lang.IllegalArgumentException: Service not registered
  • problem 3: Why has it been implemented unBindService Methods can still reference bindings service Methods ?
    problem 3 This leads to the problem of memory leakage , By looking at

Reference material

https://blog.csdn.net/qq_33718648/article/details/79880105
https://blog.csdn.net/oudetu/article/details/79279596

原网站

版权声明
本文为[Shuangmu green orange]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206111724524048.html