是时候干掉onActivityResult了

原创 2017年11月14日 19:08:41

两个冤家,handler与onActivityResult

安卓中有两个我们常用,但写起来非常不爽的代码。一个是handler,另一个就是onActivityResult了。他们非得让我们都整一个常量,而且看代码时请求和处理逻辑之间跳来跳去。一个字,晕。
我们知道handler大部分用在网络请求上,至于去掉可以看我以前的文章安卓项目易用Ohttp封装,当然这个网络请求封装很多。但对onActivityResult封装的并不多。

要实现的目标代码

这里我要说下,当我们想实现一个东西时。不是先想怎么实现,而是先想我们要实现什么样的,首先我们不要requestCode,其次我们要回调:

 startActivityForResult(new Intent(this, MainActivity.class), new ResultBack() {
            @Override
            public void resultOk(Intent data) {
                //to do what you want when resultCode == RESULT_OK
            }
        });

实现分析

1.有人说使用进程注入的方式hook系统的activity数据发送,这个不好实现,也不建议这样。
2.使用代理的Activity或fragment,如果使用单例,就需要解决不同activity回调的生命周期,而使用每个新建一个的话,每个请求new一个activity或fragment对象开销太大。
3.进行简单封装,跟随调用对象的生命周期,这个简单,而且易于使用和理解。

实现代码

首先我们看到上面有个回调接口,只写了成功的部分,有同学就问,你这我怎么处理失败或其他自定义的resultCode,看代码:

public abstract class ResultBack {
    public abstract void resultOk(Intent data);
    public void resultElse(int resultCode, Intent data){
    //可以吧,如果要处理其他情况只需重写此方法。大部分时候我们是不要用的
    }
}

简单封装

重点来了,我们是怎么干掉requestCode的呢?说简单也简单,相信你一看就懂。只需在基类BaseActivity和BaseFragment加上下面这些代码就行了

private ArrayList<ResultBack> list = new ArrayList<>();//保存所有activity返回的回调,跟随activity生命周期

public synchronized void startActivityForResult(Intent intent, ResultBack resultBack) {
     if (list.indexOf(resultBack) < 0) {
         list.add(resultBack);
         startActivityForResult(intent, list.size());//requestCode就是list的Index,哈哈哈
     }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
         list.get(resultCode).resultOk(data);
    } else {
        list.get(resultCode).resultElse(resultCode, data);
    }
    list.set(requestCode, null);//释放已返回的ResultBack,不用remove防止乱序
}

小优化

因为每个请求会生成一个ResultBack回调对象,点击一下生成一个,所以建议这样用,当然也可以不用,因为点了就跳了也点不了几下:

private ResultBack mainBack = new ResultBack() {
     @Override
     public void resultOk(Intent data) {
     }
};
public void any(){
    startActivityForResult(new Intent(this, MainActivity.class), mainBack);
}
版权声明:本文为博主原创文章,转载请注明出处。

Activity的生命周期函数、onActivityResult、intent和启动模式的调用关系

将activity的启动模式和intent传值问题进行了总结和思考
  • cbzcbzcbzcbz
  • cbzcbzcbzcbz
  • 2017年07月25日 11:14
  • 380

Andriod中多层fragment相套时onActivityResult()方法不被调用的原因

Fragment是常用到的,一般在Activity里我们会套用Fragment的使用,有时是一层,有的时候是多层,当你在第二层的Fragment中调用onActivityResult()方法时,你会发...
  • shihuiyun
  • shihuiyun
  • 2016年06月15日 14:02
  • 760

Android的onActivityResult不被调用的解决方案

方案一: 现象: startActivityForResult() 后直接调用 onActivityResult()。 开发人员都知道,可以通过使用 startActivityForResult(...
  • xuhuan_wh
  • xuhuan_wh
  • 2016年09月19日 15:27
  • 4160

SingleTask与onActivityResult之间关系的简单讨论

很多博客里说,在LaunchMode设置为SingleTask之后,是调用方的onActivityResult会在打开的瞬间被调用,无法取得正常的结果,因此来验证一下。 概括以下大写字母均表示为Act...
  • dingding_android
  • dingding_android
  • 2015年11月06日 12:20
  • 2280

Android的Fragment中onActivityResult不被调用的解决方案(绝对管用)

常见的,我们会在FragmentActivity中嵌套一层Fragment使用,甚至Fragment下层层嵌套使用。这个时候,在第二级或者更深级别的Fragment将无法收到onActivityRes...
  • shuaihj
  • shuaihj
  • 2015年06月27日 18:16
  • 49835

Android onActivityResult获取返回值的用法

现有MainActivity,当它进入到SecondActivity后,在SecondActivity中进行了某些操作然后需要将值返回给MainActivity时, 于是就可以用到onActivit...
  • u011246046
  • u011246046
  • 2015年02月06日 12:21
  • 1409

Android的Fragment中onActivityResult不被调用的最终解决方案

摘自:http://www.myexception.cn/android/1908553.html Fragment中的onActivityResult不被调用,有几种情况,请大家一...
  • aiguoguo000
  • aiguoguo000
  • 2016年06月25日 15:56
  • 2902

【小知识点总结】startActivityForResult 和onActivityResult 的用法及【遇到的问题】

利用startActivityForResult 和 onActivityResult在activity间传递数据 AndroidManifest.xml             android:...
  • Jason_996
  • Jason_996
  • 2015年08月24日 17:58
  • 843

compileSdkVersion为23以下的应用运行在Android6.0的拍照权限处理(拍照时onActivityResult的data返回为null的处理办法)

compileSdkVersion在23以下的应用运行在Android6.0的拍照权限处理[拍照时onActivityResult的data返回为null的处理办法]场景还原我以前开发的一个项目中需要...
  • qq137722697
  • qq137722697
  • 2016年10月15日 16:06
  • 1149

完美解决Android中onActivityResult提前执行调用的一系列问题

这是原本要启动的AddressActivityint requestCode = 200; Intent intent = new Intent(this,AddressActivity.class)...
  • codekxx
  • codekxx
  • 2016年12月06日 23:20
  • 1404
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:是时候干掉onActivityResult了
举报原因:
原因补充:

(最多只允许输入30个字)