巧用Fragment解耦onActivityResult

最近在研究jsbridge, 一直在想怎么样才能让需要startActivityForResult比如打开相机拍照这样的操作在webView中能更简单一点, 直到我发现了这篇文章

两个类,让你再也不用实现onActivityResult()

看了之后, 马上模仿了文中的代码实现了一下.
Fragment:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class OnActResultEventDispatcherFragment extends Fragment{
public static final String TAG = "on_act_result_event_dispatcher";

public int mRequestCode = 0x11;

private SparseArray<ActResultRequest.Callback> mCallbacks = new SparseArray<>();

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

public void startForResult(Intent intent, ActResultRequest.Callback callback) {
// mRequestCode与callback需要一一对应
mCallbacks.put(mRequestCode, callback);
startActivityForResult(intent, mRequestCode);
mRequestCode++;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

ActResultRequest.Callback callback = mCallbacks.get(requestCode);
mCallbacks.remove(requestCode);

if (callback != null) {
callback.onActivityResult(resultCode, data);
}
}

}

ActResultRequest:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class ActResultRequest {

private OnActResultEventDispatcherFragment fragment;

public ActResultRequest(FragmentActivity activity) {
fragment = getEventDispatchFragment(activity);
}

private OnActResultEventDispatcherFragment getEventDispatchFragment(FragmentActivity activity) {
FragmentManager fragmentManager = activity.getSupportFragmentManager();


OnActResultEventDispatcherFragment fragment = findEventDispatchFragment(fragmentManager);
if (fragment == null) {
fragment = new OnActResultEventDispatcherFragment();
fragmentManager
.beginTransaction()
.add(fragment, OnActResultEventDispatcherFragment.TAG)
.commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
}
return fragment;
}

private OnActResultEventDispatcherFragment findEventDispatchFragment(FragmentManager manager) {
return (OnActResultEventDispatcherFragment) manager.findFragmentByTag(OnActResultEventDispatcherFragment.TAG);
}

public void startForResult(Intent intent, Callback callback) {
fragment.startForResult(intent, callback);
}

public interface Callback {

void onActivityResult(int resultCode, Intent data);
}
}

MainActivity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";

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

public void start(View view) {
Intent intent = new Intent(this, SecondActivity.class);
ActResultRequest request = new ActResultRequest(this);
request.startForResult(intent, new ActResultRequest.Callback() {
@Override
public void onActivityResult(int resultCode, Intent data) {
Log.d(TAG, "resultCode = " + resultCode);
String name = data.getStringExtra("name");
Log.d(TAG, "name = " + name);
Toast.makeText(MainActivity.this, "name = " + name + ", resultCode = " + resultCode,
Toast.LENGTH_SHORT).show();
}
});
}
}

SecondActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class SecondActivity extends AppCompatActivity {

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

}

public void returnResult(View view) {
Intent intent = new Intent();
intent.putExtra("name", "mundane");
setResult(RESULT_OK, intent);
finish();

}
}

按照这样的思路, 如果需要简化jsbridge中startActivityForResult的操作, 我们只需要把Fragment和WebView绑定在一起.比如给这个Fragment取名叫WebViewFragment, 它的布局中只有一个我们封装好的WebView, 这个WebView需要监听jsbridge的所有事件我们都在fragment中写好, 包括onActivityResult中的事件, 当然也可以在这个fragment中用一个专门的管理类来管理注册的事件.以后Activity中有用到WebView的地方我们就直接用这个WebViewFragment就好了.也就是说, 把这个WebViewFragment, 当成我们之前的WebView.

github地址:

EasyOnActivityResult

0%