可以代替 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 获取数据
 * 

* 暂时考虑不使用单例,用后即焚 */ 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 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()


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

你可能感兴趣的:(可以代替 onActivityResult 的办法)