Android 关于service

一直以为stopService和unbindService可以销毁service运行的耗时操作,但是发现执行前面两个方法只是执行了ondestory方法,运行的耗时操作仍然在后台运行,代码如下所示:

public class StartServiceActivity extends BaseActivity {
    private Button startButton;
    private Button stopButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    protected void initView() {
        setContentView(R.layout.activity_start_service);
        startButton = f(R.id.startButton);
        stopButton = f(R.id.stopButton);
        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startService(new Intent(StartServiceActivity.this, MyService.class));
            }
        });

        stopButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                stopService(new Intent(StartServiceActivity.this, MyService.class));
            }
        });

    }

    @Override
    protected void loadData() {

    }
}

service代码如下:

public class MyService extends Service {
    private static final String TAG = "MyService";
    private static final int MAX = 100;
    private int currentProsess;
    private Handler handler = new Handler();
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            currentProsess++;
            Log.d(TAG, "run() called======" + currentProsess);
            handler.postDelayed(runnable, 1000);
        }
    };

    public MyService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate() called");
        handler.post(runnable);
    }


    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
//发现使用stopSelf();也并不能关闭耗时操作
//        stopSelf();
//解决办法是在onDestory里面自己手动解决耗时操作
        handler.removeCallbacks(runnable);
        Log.d(TAG, "onDestroy() called");
    }
}
下面是onDestroy()方法中执行stopSelf();的方法,发现耗时操作并未停止运行;
2019-07-27 23:38:28.920 24590-24590/com.example.hasee.water D/MyService: onCreate() called
2019-07-27 23:38:28.921 24590-24590/com.example.hasee.water D/MyService: onStartCommand() called with: intent = [Intent { cmp=com.example.hasee.water/.service.MyService }], flags = [0], startId = [1]
2019-07-27 23:38:28.922 24590-24590/com.example.hasee.water D/MyService: run() called======1
2019-07-27 23:38:29.923 24590-24590/com.example.hasee.water D/MyService: run() called======2
2019-07-27 23:38:30.925 24590-24590/com.example.hasee.water D/MyService: run() called======3
2019-07-27 23:38:31.929 24590-24590/com.example.hasee.water D/MyService: run() called======4
2019-07-27 23:38:32.838 24590-24590/com.example.hasee.water D/MyService: onDestroy() called
2019-07-27 23:38:32.930 24590-24590/com.example.hasee.water D/MyService: run() called======5
2019-07-27 23:38:33.933 24590-24590/com.example.hasee.water D/MyService: run() called======6
2019-07-27 23:38:34.934 24590-24590/com.example.hasee.water D/MyService: run() called======7

下面是onDestroy()方法里执行handler.removeCallbacks(runnable);此时耗时操作停止运行,所以我们想终止服务里运行的耗时操作,我们应该手动去移除

2019-07-27 23:38:28.920 24590-24590/com.example.hasee.water D/MyService: onCreate() called
2019-07-27 23:38:28.921 24590-24590/com.example.hasee.water D/MyService: onStartCommand() called with: intent = [Intent { cmp=com.example.hasee.water/.service.MyService }], flags = [0], startId = [1]
2019-07-27 23:38:28.922 24590-24590/com.example.hasee.water D/MyService: run() called======1
2019-07-27 23:38:29.923 24590-24590/com.example.hasee.water D/MyService: run() called======2
2019-07-27 23:38:30.925 24590-24590/com.example.hasee.water D/MyService: run() called======3
2019-07-27 23:38:31.929 24590-24590/com.example.hasee.water D/MyService: run() called======4
2019-07-27 23:38:32.838 24590-24590/com.example.hasee.water D/MyService: onDestroy() called

 

关于activity和service交互的问题:

我们不能使用startService来启动,因为activity拿不到启动的service,只能通过bindService来启动,因为service通过

onBind方法可以返回binder,而我们在activity中可以通过ServiceConnection的onServiceConnected拿到binder,通过binder来操作service中的方法,这样他们就关联上了:

 

activity中的代码:

public class DownLoadActivity extends BaseActivity {
    private static final String TAG = "DownLoadActivity";
    private static final String TAG1 = "DownLoadService";
    private Button downLoadButton,unBindServicebutton;
    private TextView downLoadProgressTextView;
    private DownLoadService downLoadService;
    private int currentProgress = 0;
    private DownLoadService.DownLoadBinder downLoadBinder;
    private boolean haveBindService;

    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            downLoadBinder = (DownLoadService.DownLoadBinder) iBinder;
            Log.d(TAG, "onServiceConnected() called with: componentName = [" + componentName + "], iBinder = [" + iBinder + "]");
            if(null!=downLoadBinder){
                downLoadBinder.startDownLoad();
            }else{
                Log.d(TAG, "onServiceConnected: 未获取到service");
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d(TAG1, "DownLoadService------onServiceDisconnected: 断开了连接");
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void initView() {
        setContentView(R.layout.activity_down_load);
        downLoadButton = f(R.id.downLoadButton);
        unBindServicebutton=f(R.id.unBindServicebutton);
        downLoadProgressTextView = f(R.id.downLoadProgressTextView);
        final Intent intent = new Intent(this,DownLoadService.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            intent.setPackage(getPackageName());
            bindService(intent, serviceConnection, BIND_AUTO_CREATE);
        } else {
            bindService(intent, serviceConnection, BIND_AUTO_CREATE);
        }
        haveBindService=true;

        downLoadButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (null != downLoadBinder) {
                    downLoadBinder.startDownLoad();
                    downLoadBinder.setDomnLoadListener(new DownLoadService.DownLoadListener() {
                        @Override
                        public void prosess(final int prosess) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    downLoadProgressTextView.setText("下载进度=" + prosess + "%");
                                }
                            });

                        }
                    });
                }
            }
        });

        unBindServicebutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(haveBindService){
                    unbindService(serviceConnection);
                    haveBindService=false;
                }

            }
        });


    }

    @Override
    protected void loadData() {

    }


}

 

service中的代码:

public class DownLoadService extends Service {
    private static final String TAG = "DownLoadService";
    private static final int TOTAL_PROGRESS=100;
    private int currentProGress=0;
    public DownLoadListener mDownLoadListener;
    private DownLoadBinder downLoadBinder=new DownLoadBinder();

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy() called-----服务被关闭");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return downLoadBinder;
    }


    public void downLoad(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (currentProGress<TOTAL_PROGRESS){
                    currentProGress+=1;
                    try {
                        Thread.sleep(1000);
                        if(null!=mDownLoadListener){
                            mDownLoadListener.prosess(currentProGress);
                            Log.d(TAG, "run() called----当前下载进度="+currentProGress);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        }).start();
        stopSelf();

    }

    public interface DownLoadListener{
        void prosess(int prosess);
    }

    public class DownLoadBinder extends Binder{
        public void startDownLoad(){
            Log.d(TAG, "startDownLoad: 开始下载.......");
            downLoad();
        }

        public int getProgress(){
            return currentProGress;
        }

        public void setDomnLoadListener(DownLoadListener domnLoadListener){
            mDownLoadListener=domnLoadListener;
        }


    }

}当然之里面在ondestory里面没有对线程进行移除,所以调用ondestory方法以后线程仍在后台继续运行,直到任务完成。注意:startService和bindService都是可以启动service,但是service的生命周期会不一样。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值