博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android:Activity与Fragment、Service之间的数据通信
阅读量:6832 次
发布时间:2019-06-26

本文共 4443 字,大约阅读时间需要 14 分钟。

1、Activity向Fragment传递数据?

  • 在Activity中创建Bundle,将数据以putString(key,value)形式放入bundle中,最后通过setArguments(bundle)方法,将其关联,在Fragment【与Activity依附的Fragment】中直接通过getArguments().getString()来获取。

  • 直接通过强转将其强转为Activity,即调用Fragment所依附的Activity中的方法。

2、Fragment将数据传递给Activity?

基本方法:接口回调;

  • 在fragment定义一个内部回调接口,再让包含这个FragmentActivity实现这个回调接口,fragment就可以调用这个接口中的方法,将数据传递给Activity。

  • Activity实现完接口后,又怎样把数据传递给Fragment,利用Fragment刚添加到Activity时的时候调用的生命周期方法的onAttch()方法,我们就在该方法中检查相应的Activity是否实现了Fragment当中定义的内部接口。就是对它进行了类型转换,然后赋值给我们Fragment中定义的接口。

  • 当一个Fragment从Activity当中剥离时,就会走到生命周期的onDetach()方法,在此要将传递进来的Activity对象释放掉,否则会影响Acitvity销毁,产生内存泄漏。

public class fragment1 extends Fragment implements View.OnClickListener{    //2.1、用来与外部Activity交互,获取宿主Activity    private FragmentListener listener;    //1、首先定义所有Activity必须实现的接口方法。    public interface FragmentListener{        void process(String str);    }    //fragment被加载到Activity时回调    @Override    public void onAttach(Activity activity) {        super.onAttach(activity);        //判断activity是否实现了FragmentListener方法        if (activity instanceof FragmentListener){            listener = (FragmentListener) activity;//获取到宿主Activity,并给你赋值。        }else{            throw new IllegalArgumentException("activity must implements Fragment");            //否则的话,会抛出activity must implements Fragment[Activity必须关联Fragment]异常。        }    }    @Override    public void onClick(View v) {        listener.process(str:"我是接口");//3.1、执行回调    }    //把传递进来的activity对象释放掉     @Override    public void onDetach() {        super.onDetach();        listener = null;//进行销毁,避免造成内存泄漏。    }}复制代码
public class FragmentActivity1 extends Activity implements fragment1.FragmentListener {         @Override        public void process(String str) {            // TODO: 2019/3/19        }}复制代码

除此以外我们想要完成Activity与Fragment之间的数据传递还可以使用:第三方框架Eventbus、广播。

3、Activity与Service数据通信?

三种方式:

1、绑定服务,利用ServiceConnection类,同时让Activity实现该类,重写该类中的两个方法,即绑定成功()和绑定失败()。

  • 让我们的ServiceActivity去实现ServiceConnection接口,实现接口之后,重写onServiceConnected()和onServiceDisconnected()两个方法。
  • 首先我们要创建好一个Binder对象,接下来在OnServiceConnected当中获取到该Binder对象。最后利用Binder当中setData()方法来向Service传递数据。

2、简单通信,利用Intent进行传值(Intent组件在activity之间、activity与fragment之间数据通信都会用到),该方法简单,但是也只能传递较简单的数据。

//在ServiceActivity中进行启动和停止服务操作        @Override        public void onClick(View v){            switch (v.getId()){                case R.id.btStartService://启动服务                    intent.putExtra(name:"data",value:"data");//(key,value)                    startService(intent);                    break;                case R.id.btStopService://启动服务                    stopService(intent);                    break;            }        }复制代码
//Service中public int onStartCommand(final Intent intent,int flags,int startId){    data = intent.getStringExtra(name:"data");//接收从Activity中传递来的值。    return super.onStartCommand(intent,flags,startId);} 复制代码

3、利用callback接口,将Handler来监听服务中的进程的变化(会有子线程到主线程的切换,因此用到了Handler)。

  • Service内部是如何实现的呢?
  • 首先添加一个公开的Callback接口,通过Activity来实现该接口。
public interface Callback{    void onDataChange(String data);}复制代码
  • 新建一个Binder类,在Binder内部定义getMyService()方法用来返回当前MyService的一个对象,让Activity可以添加该事件的绑定。
public class Binder extends android.os.Binder{    public void setData(String data){        MyService.this.data = data;    }    public MyService getMyService(){        return MyService.this;    }}复制代码
  • 那么外部Activity是如何添加绑定的呢?
  • 首先onServiceConnected()方法,一旦调用该方法,就说明我们的Service与Activity之间绑定成功了。实现过程:调用setCallback()方法,实现onDataChange()方法。除此之外,由于我们onDataChange()是在子线程中执行【在子线程中更新UI,要使用到Handler】,在此我们使用Handler发送一个Message,在主线程中我们定义了一个Handler,并实现了它的handlerMessage()方法,即将任务从子线程切换到了主线程,让主线程来进行UI操作。
private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg){            super.handleMessage(msg);        }    };     //一旦绑定成功就会执行该函数    @Override    public void onServiceConnected(ComponentName componentName,Ibinder iBinder){        myBinder = (MyService.Binder) iBinder;        myBinder.getMyService().setCallback(new MyService.callback() {            Message msg = new Message();            Bundle b = new Bundle();            b.putString("data",data);            msg.setData(b);            handler.sendMessage(msg);        });    }复制代码

最后送福利了,现在关注我并且加入群聊可以获取包含源码解析,自定义View,动画实现,架构分享等。 内容难度适中,篇幅精炼,每天只需花上十几分钟阅读即可。 大家可以跟我一起探讨,欢迎加群探讨,有flutter—性能优化—移动架构—资深UI工程师 —NDK相关专业人员和视频教学资料,还有更多面试题等你来拿~ 群号:661841852

点击链接加入群聊【Android开发行业交流】:

转载于:https://juejin.im/post/5cd42e97e51d453b560f2d69

你可能感兴趣的文章
HTML5介绍
查看>>
图片的title属性和alt属性的区别
查看>>
iOS社会化分享(干货)
查看>>
第八章实验报告
查看>>
使用 gzexe 快速加密解密文件内容
查看>>
java jvm学习笔记十(策略和保护域)
查看>>
C# Task中的Func, Action, Async与Await的使用
查看>>
[百度杯-二月场](Misc-Web)爆破-2
查看>>
移除jQuery绑定的click历史事件
查看>>
时间管理
查看>>
[技巧心得] CSS中文字体对照表
查看>>
[Android Pro] service中显示一个dialog 或者通过windowmanage显示view
查看>>
Linux(CentOS)挂载移动硬盘
查看>>
JaveWeb 公司项目(7)----- 通过JS动态生成DIV
查看>>
python_控制台输出带颜色的文字方法
查看>>
TiDB 深度实践之旅--真实“踩坑”经历
查看>>
通过Cloudera Manager安装CDH 5.6
查看>>
Android通过JNI实现与C语言的串口通讯操作蓝牙硬件模块
查看>>
《Java实战开发经典》第五章5.3
查看>>
Codeforces Round #247 (Div. 2) D. Random Task
查看>>