可以代替 onActivityResult 的办法

1. 代替重写 Activity 的 onActivityResult

项目中比较多的,某一个Activity使用startActivityForResult()Target Actiivty拿一个结果,之前在网上看到一个方案,通过借助一个无视图的Fragment来进行实现,这样没必要重写onActivityResult(),借鉴下思路,改了下代码,用在了项目中,暂时也没发现有什么问题

使用场景:同一个进程的中的两个Activity来使用

1.0 StartForResultManager

/**
 * @author g&c
 * @date 2018/01/15
 * 避免使用 onActivityResult
 * 通过一个没有视图的 Fragment
 * 从 Target Activity 获取数据
 * <p>
 * 暂时考虑不使用单例,用后即焚
 */
public class StartForResultManager {
    private static final String TAG = StartForResultManager.class.getSimpleName();
    private StartCallbackFragment mStartCallbackFragment;

    /**
     * 跳转 Activity 的 Class 对象
     */
    private Class<?> mTargetClass;

    /**
     * 从开始 Activity 传给数据源目标 Activity的数据
     */
    private Bundle mDataBundle;

    public static StartForResultManager get() {
        return new StartForResultManager();
    }

    private StartForResultManager() {
    }

    public StartForResultManager from(Activity activity) {
        mStartCallbackFragment = crateStartCallbackFragment(activity);
        return this;
    }

    public StartForResultManager from(Fragment fragment) {
        this.from(fragment.getActivity());
        return this;
    }

    public StartForResultManager to(Class<?> clazz) {
        this.mTargetClass = clazz;
        return this;
    }


    public StartForResultManager bundle(Bundle bundle) {
        mDataBundle = new Bundle(bundle);
        return this;
    }

    /**
     * 开启目标 Activity
     *
     * @param callback 结果回调
     */
    public void startForResult(@NonNull CallbackAdapter callback) {
        if (mStartCallbackFragment == null) {
            throw new NullPointerException("From activity is null , forget from() ?");
        }
        Activity activity = mStartCallbackFragment.getActivity();
        if (activity == null) {
            // 若为 Activity 为 Null,说明场景不再适合使用 StartForResultManager
            throw new NullPointerException("Surprise , something is error , perhaps this is love");
        }
        if (mTargetClass == null) {
            throw new NullPointerException("mTargetClass is null , forget to() ?");
        }
        Intent intent = new Intent(activity, mTargetClass);
        if (mDataBundle != null) {
            intent.putExtras(mDataBundle);
        }
        fragmentStartForResult(intent, callback.hashCode(), callback);
    }

    /**
     * 创建中间桥梁 Fragment
     *
     * @param activity 启动 Activity :桥梁 Fragment 所依赖的 Activity
     * @return Fragment
     */
    private StartCallbackFragment crateStartCallbackFragment(Activity activity) {
        StartCallbackFragment resultFragment = findStartCallbackFragment(activity);
        if (resultFragment == null) {
            resultFragment = new StartCallbackFragment();
            FragmentManager fragmentManager = activity.getFragmentManager();
            fragmentManager
                    .beginTransaction()
                    .add(resultFragment, TAG)
                    .commitAllowingStateLoss();
            fragmentManager.executePendingTransactions();
        }
        return resultFragment;
    }

    /**
     * 查找中间桥梁 Fragment
     *
     * @param activity 启动 Activity
     * @return Fragment
     */
    private StartCallbackFragment findStartCallbackFragment(Activity activity) {
        return (StartCallbackFragment) activity.getFragmentManager().findFragmentByTag(TAG);
    }

    /**
     * 通过桥梁 Fragment 启动数据源目标 Activity
     *
     * @param intent      Intent
     * @param requestCode 请求码
     * @param callback    结果回调
     */
    private void fragmentStartForResult(Intent intent, int requestCode, CallbackAdapter callback) {
        mStartCallbackFragment.startForResult(intent, requestCode, callback);
    }

    /**
     * 结果回调适配
     */
    public static class CallbackAdapter implements Callback {

        @Override
        public void onResultError() {

        }

        @Override
        public void onActivityResult(int resultCode, Intent data) {

        }
    }

    /**
     * 结果回调接口
     */
    private interface Callback {

        /**
         * 当拿结果出现错误时
         * 当 Intent data 为 null 时
         */
        void onResultError();

        /**
         * 结果回调
         *
         * @param resultCode 结果码
         * @param data       数据
         */
        void onActivityResult(int resultCode, Intent data);
    }
}

1.1 StartCallbackFragment

无视图的中间桥梁 Fragment

/**
 * @author g&c
 * @date 2018/01/15
 * 桥梁,没有界面
 * 利用 startForResult(),onActivityResult()方法
 * 从目标数据源 TargetActivity 获取数据,返回到启动的 Activity
 */
public final class StartCallbackFragment extends Fragment {
    /**
     * 存放 Callback
     */
    private SparseArray<StartForResultManager.CallbackAdapter> mCallbackArr;

    public StartCallbackFragment() {
        mCallbackArr = new SparseArray<>();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    /**
     * StartCallbackFragment 开启目标 Activity
     *
     * @param intent      意图
     * @param requestCode 请求码
     * @param callback    回调
     */
    public void startForResult(Intent intent, int requestCode,
                               StartForResultManager.CallbackAdapter callback) {
        mCallbackArr.put(requestCode, callback);
        startActivityForResult(intent, requestCode);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // Callback 结果回调
        StartForResultManager.CallbackAdapter callback = mCallbackArr.get(requestCode);
        if (callback == null) {
            return;
        }
        // 移除 Callback
        mCallbackArr.remove(requestCode);
        if (data == null) {
            // 回调错误方法
            callback.onResultError();
            return;
        }
        // 结果回调
        callback.onActivityResult(resultCode, data);
    }
}

CallbackAdapter有两个方法,使用时,若不关心拿到不到结果的情况,就没必要重写onResultError()方法,只关心onActivityResult()就可以

2. 使用

2.1 来源Activity

public class StartCallbackActivity extends AppCompatActivity {
    private TextView mTvContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start_callback);
        initView();
    }

    private void initView() {
        Button bt = findViewById(R.id.activity_start_callback_bt);
        mTvContent = findViewById(R.id.activity_start_callback_tv);
        bt.setOnClickListener(v -> start("116", "20180116 You happy, You ok"
                , StartCallbackResultActivity.class));

        Button bt2 = findViewById(R.id.activity_start_callback_bt2);
        bt2.setOnClickListener(v -> start("117", "20180116 This is love"
                , StartCallbackResult2Activity.class));
    }

    private void start(String key, String value, Class<?> cla) {
        // 数据
        Bundle b = new Bundle();
        b.putString(key, value);

        // 跳转
        StartForResultManager
                .get()
                .from(StartCallbackActivity.this)
                .to(cla)
                .bundle(b)
                .startForResult(new StartForResultManager.CallbackAdapter() {
                    @Override
                    public void onActivityResult(int resultCode, Intent data) {
                        super.onActivityResult(resultCode, data);
                        String str = data.getStringExtra("text");
                        if (resultCode == Activity.RESULT_OK && !TextUtils.isEmpty(str)) {
                            mTvContent.setText(str);
                        }
                    }

                    @Override
                    public void onResultError() {
                        super.onResultError();
                        String str = "没有返回有效数据";
                        mTvContent.setText(str);
                    }
                });
    }
}

布局就是两个Button,一个TextView,点击一个Button跳转对应的一个Target Activity,然后在Target Activity使用setResult()来返回结果显示在TextView

StartCallbackActivity来源 Activity

StartCallbackResultActivity,StartCallbackResult2Activity为两个不同的 Target Activity

2.1 Target Activity

StartCallbackResultActivity中有一个Button,点击将数据返回

/**
 * @author g&c
 * @date 2018/01/15
 * Target Activity
 * 接收来源 Activity 传递过来的一个字符串
 * 返回给来源 Activity 一个字符串
 */
public class StartCallbackResultActivity extends AppCompatActivity {
    private String mStringData = "-1";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start_callback_result);
        getData();
        initView();
    }

    private void getData() {
        Intent intent = getIntent();
        if (intent == null) {
            return;
        }
        Bundle extras = intent.getExtras();
        if (extras == null) {
            return;
        }
        mStringData = (String) extras.get("116");
    }

    private void initView() {
        Button bt = findViewById(R.id.activity_start_result_bt);
        bt.setOnClickListener(v -> {
            Intent intent = new Intent();
            intent.putExtra("text", "12345678");
            setResult(Activity.RESULT_OK, intent);
            finish();
        });

        TextView tv = findViewById(R.id.activity_start_result_tv);
        tv.setText(mStringData);
    }
}

关键就一个setResult()方法

3. 最后

使用说明:

StartForResultManager必须 调用from()指定来源 Activity,使用to()来指定Target Activity,否则StartForResultManager.startForResult()方法中会抛出NullPointerException,可以看一眼代码

来源 Activity需要将数据传递到Target Activity,可以使用bundle()传递一个Bundle,若不需要数据,就没必要调用bundle()

若使用时,有啥问题,或者遇到不适合使用的场景,请留言指出

    原文作者:英勇青铜5
    原文地址: https://www.jianshu.com/p/a75f57adbb30
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞