需求
- 用WebView加载网页商城,内存泄露问题
- 商城调用APP支付(微信支付和支付宝支付)
解决方案
针对需求1
在新的进程中开启加载WebView的界面,在页面退出之后,关闭该进程
- 开启新进程的方法
通常我们会使用修改清单文件的android:process来达到目的。
不了解多进程的可以参考:传送
<activity
android:name=".web.StoreWebActivity"
android:process="com.test.web"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan">
</activity>
- 当WebView退出时,在WebView所在的Activity中,杀死WebView所在的进程
@Override
public void onDestroy() {
android.os.Process.killProcess(android.os.Process.myPid());
super.onDestroy();
}
解决问题2
因为WebView在新的进程中,导致
WXPayEntryActivity
和StoreWebActivity
不在一个进程中,导致在onResq
回调处理支付结果时,callback
为null
当然有人会说把WxPayEntryActivity也放在com.test.web
这个进程中不就好了,我没有尝试是否可以,因为微信支付也会主进程中调用
这个时候就需要处理WxPayEntryActivity
和StoreWebActivity
之间的跨进程通信问题
- 跨进程通信的方案有很多,可以参考这篇文章传送,我也是参考这篇文章中的方案解决--使用Messenger解决跨进程通信
- 创建一个和
StoreWebActivity
的相同进程的Service
<service android:name=".MessengerService"
android:process="com.test.web"/>
MessagerService的代码如下:
public class MessengerService extends Service {
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
WechatPay.getInstance().onResp(msg.what);
}
}
Messenger mMessenger = new Messenger(new IncomingHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
- 然后修改
WxPayEntryActivity
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI api;
String processName;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
processName = BMApplication.getProcessName();
if (!TextUtils.isEmpty(processName) && processName.equals(this.getPackageName())) {
}else{
Intent intent = new Intent(WXPayEntryActivity.this, MessengerService.class);
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
}
api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
api.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
}
private int code = -1;
@Override
public void onResp(BaseResp resp) {
if (!TextUtils.isEmpty(processName) && processName.equals(this.getPackageName())) {//判断进程名,保证只有主进程运行
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
WechatPay.getInstance().onResp(msg.what);
WXPayEntryActivity.this.finish();
}
} else {
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
code = resp.errCode;
}
}
}
private boolean mBound;
private Messenger mMessenger;
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMessenger = new Messenger(service);
mBound = true;
deal(code);
}
@Override
public void onServiceDisconnected(ComponentName name) {
deal(code);
mMessenger = null;
mBound = false;
}
};
@Override
protected void onStop() {
super.onStop();
if (mBound) {
unbindService(mServiceConnection);
mBound = false;
}
}
private void deal(int code) {
if (!mBound) {
return;
}
Message msg = Message.obtain(null, code);
try {
mMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
WXPayEntryActivity.this.finish();
}
}
网友评论