Service中bindService

Service中bindService最近有用到Activity需要不断的从Service中获取数据,第一个想法肯定就是通过bind回调机制了,有几点概念模糊特此记录下:单独使用bindService(),unbindService()会经历:->onCreate()->onBind()->Servicerunning->onUnbind()->onDestroy()。单独使用startSer…

大家好,又见面了,我是你们的朋友全栈君。

最近有用到Activity需要不断的从Service中获取数据,第一个想法肯定就是通过bind回调机制了,有几点概念模糊特此记录下:

单独使用bindService(),unbindService()会经历:->onCreate()->onBind()->Service running->onUnbind() -> onDestroy() 。

单独使用startService(),stopService()会经历:->onCreate()->onStartCommand()->Service running-> onDestroy() 。

先调用startService(),再调用bindService()方法:

如果结束只调用unbindService(),那么只会执行到onUnbind(),将不会执行onDestroy():->onCreate()->onStartCommand()->onBind()->Service running-> onUnbind()。
如果在unbindService后,在调用stopService(),那么:->onCreate()->onStartCommand()->onBind()->Service running-> onUnbind()->onDestroy() 。
1、绑定的Service只有当应用组件绑定后才能运行,多个组件可以绑定一个Service,当调用unbind()方法时,这个service就会被销毁了。
2、Service与Activity一样都存在与当前进程的主线程中,所以,一些阻塞UI的操作,比如耗时操作不能放在service里进行,比如另外开启一个线程来处理诸如网络请求的耗时操作。如果在service里进行一些耗CPU和耗时操作,可能会引发ANR警告,这时应用会弹出是强制关闭还是等待的对话框。所以,对service的理解就是和activity平级的,只不过是看不见的,在后台运行的一个组件,这也是为什么和activity同被说为Android的基本组件。
3、图形理解Service:
在这里插入图片描述
通过这个图可以看到,两种启动Service的方式以及他们的生命周期,bindService的不同之处在于当绑定的组件销毁后,对应的Service也就被kill了。Service的声明周期相比与Activity的简单了许多,只要好好理解两种启动service方式的异同就行。
4、关于停止Service,如果service是非绑定的,最终当任务完成时,为了节省系统资源,一定要停止service,可以通过stopSelf()来停止,也可以在其他组件中通过stopService()来停止,绑定的service可以通过onUnBind()来停止service。

关于Activity与Service数据的互相传递,写了个demo:

public class MainActivity extends Activity implements View.OnClickListener {
    private  TextView mTextView;
    private EditText mEditText;
    private MyService.LocalBinder binder=null;
    MyService myService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mEditText = (EditText) findViewById(R.id.edt_content);
        Button mBtnStart = (Button) findViewById(R.id.btn_start);
        Button mBtnClose = (Button) findViewById(R.id.btn_close);
        Button mBtnSubmit = (Button) findViewById(R.id.btn_submit);
        mTextView = (TextView) findViewById(R.id.tv_show);
        mBtnStart.setOnClickListener(this);
        mBtnClose.setOnClickListener(this);
        mBtnSubmit.setOnClickListener(this);
    }
    public ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            binder = (MyService.LocalBinder) service;//得到LocalBinder实例
            myService = binder.getService();//得到Service实例
            //设置接口回调获取Service中的数据
            myService.setOnDataCallback(new MyService.OnDataCallback() {
                @Override
                public void onDataChange( final String message) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mTextView.setText(message);
                        }
                    });
                }
            });
        }
 
        @Override
        public void onServiceDisconnected(ComponentName name) {
            myService = null;
        }
    };
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(this,MyService.class);
        switch (v.getId()){
            case R.id.btn_start:
//                startService(intent);
                bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);//为Activity绑定服务
                break;
            case R.id.btn_close:
                unbindService(mServiceConnection);//解除绑定
//                stopService(intent);
                break;
            case R.id.btn_submit:
                if(binder!=null){
                    //把数据传给Service,相比用Bundle效率更高
                    binder.setData(mEditText.getText().toString());
                }
                break;
        }
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mServiceConnection);//解除绑定
    }
}

MyService:

public class MyService extends Service {
    private String message ;
    private boolean isRunning = true;
    private IBinder binder = new LocalBinder();
    public class LocalBinder extends Binder {
        public void setData(String message) {
            //从Activity传入message值
            MyService.this.message = message;
        }
 
        public MyService getService() {
            //返回当前MyService对象
            return MyService.this;
        }
    }
    private OnDataCallback mOnDataCallback=null;
 
    public void setOnDataCallback(OnDataCallback mOnDataCallback) {
        this.mOnDataCallback = mOnDataCallback;
    }
 
    public interface OnDataCallback{
        void onDataChange(String message);
    }
    @Override
    public IBinder onBind(Intent intent) {
        //返回这个LocalBinder对象,其实这个对象可以在Activity中onServiceConnected()方法中接收到,这个bind就是Activity和Service通信的桥梁
        //因为在Activity通过这个bind对象可以得到Service的实例引用。一旦Service对象找到,就能得到它的公共方法和属性。
        return binder;
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
        new Thread() {
            @Override
            public void run() {
                int i=1;
                while (isRunning) {
                    if(mOnDataCallback!=null){
                        mOnDataCallback.onDataChange(message + i);
                    }
                    i++;
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
 
    }
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }
 
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
        isRunning = false;
    }
}

Activity能进行绑定得益于Service的接口onBind()。Service和Activity的连接可以用ServiceConnection来实现,需要实现一个新的ServiceConnection,重写onServiceConnected和onServiceDisconnected方法。执行绑定,调用bindService方法,传入一个选择了要绑定的Service的Intent(显式或隐式)和一个你实现了的ServiceConnection实例。一旦连接建立,你就能通Service的接口onBind()得到mBinder实例进而得到Service的实例引用。一旦Service对象找到,就能得到它的公共方法和属性。但这种方式,只能在同一个进程和同一个Application里。跨进程跨应用通信IPC需要建立aidl文件(注:Android5.0以后跨应用只能通过显示Intent来启动Service,即包名、类名)。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/132693.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 银行风控模型

    银行风控模型风控催生原因对于银行来说,现今互联网贷款和信用卡办理面临的主要难题是数据和风控。站在银行或金融机构角度,自然而然是想获得更多的信息和数据,但是在收集数据这方面又是比较无力的。加上当下的发展趋势,消费贷以及贷款审批速度都要求快。如何在快的的过程中对客户进行一个全面的审查,得出一个合理的结果呢?如果没有详细的数据对客户进行评估,这势必会提高放贷的风险。风控概述所谓风控,是指多银行贷款资金的…

  • 《SiamFC++:Towards Robust and Accurate Visual Tracking with Target Estimation Guidelines》论文笔记

    《SiamFC++:Towards Robust and Accurate Visual Tracking with Target Estimation Guidelines》论文笔记参考代码:video_analyst1.概述导读:这篇文章指出之前的一些跟踪算法没有深入讨论针对跟踪任务的实质,很多时候只是在某些点上进行突破,因而最后方法的性能总是有局限性的。对此文章深入分析了跟踪网络的特性,因而对跟踪网络的设计提出了4点建议:G1(目标位置估计和目标判别需要接耦,分别具有各自的分支)/G2(目标判别置信度不能与实际相模糊)/G3(不能依赖数据分布等先验知识,否则导致泛化性鲁棒性不强)/G4(目标位置的估计应该准确)。正是基于上的4点设计指导,文章设计了SiamFC++网络,在5

  • QTreeView中finditems查找子项

    QTreeView中finditems查找子项1、QListQStandardItemModel::findItems(constQString&text,Qt::MatchFlagsflags=Qt::MatchExactly,intcolumn=0)const不特殊指定第二个参数的情况下,此函数只会搜索TreeView的顶层元素,不会匹配子元素。第二个参数中加入“Qt::MatchContains|Q

  • 云麦体脂秤怎么拆开(云麦好轻体脂秤如何校准)

    如果是一个真正的体脂秤就好了:华为智能体脂秤2019-06-2617:12:0034点赞11收藏25评论家里十几块钱的体重秤电池没电了,电池仓用螺丝刀也搞不开,不得已买个新的吧。这两年体脂秤吹的火,就也来尝尝鲜。平时在健身房经常使用Inbody的体质测试仪器(一种高级体脂秤),所以看到体脂秤广告里说的人体生物电啊,测体脂啊,多项直标啊什么的,还是挺期待。毕竟健身房的体测仪需要密码才能用,如果…

  • 什么是差分数组?「建议收藏」

    什么是差分数组?「建议收藏」问题背景如果给你一个包含5000万个元素的数组,然后会有频繁区间修改操作,那什么是频繁的区间修改操作呢?比如让第1个数到第1000万个数每个数都加上1,而且这种操作时频繁的。此时你应该怎么做?很容易想到的是,从第1个数开始遍历,一直遍历到第1000万个数,然后每个数都加上1,如果这种操作很频繁的话,那这种暴力的方法在一些实时的系统中可能就拉跨了。因此,今天的主角就出现了——差分数组。…

  • ubuntu7.04的设置

    ubuntu7.04的设置

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号