美文网首页
WebView内存泄露与跨进程通信

WebView内存泄露与跨进程通信

作者: zhangwlhaut | 来源:发表于2017-12-09 12:15 被阅读0次

    需求

    1. 用WebView加载网页商城,内存泄露问题
    2. 商城调用APP支付(微信支付和支付宝支付)

    解决方案

    针对需求1

    在新的进程中开启加载WebView的界面,在页面退出之后,关闭该进程

    1. 开启新进程的方法
      通常我们会使用修改清单文件的android:process来达到目的。
      不了解多进程的可以参考:传送
     <activity
                android:name=".web.StoreWebActivity"
                android:process="com.test.web"
                android:screenOrientation="portrait"
                android:windowSoftInputMode="adjustPan">
    </activity>
    
    1. 当WebView退出时,在WebView所在的Activity中,杀死WebView所在的进程
    @Override
    public void onDestroy() {
            android.os.Process.killProcess(android.os.Process.myPid());
            super.onDestroy();
     }
    

    解决问题2

    因为WebView在新的进程中,导致WXPayEntryActivityStoreWebActivity不在一个进程中,导致在onResq回调处理支付结果时,callbacknull
    当然有人会说把WxPayEntryActivity也放在com.test.web这个进程中不就好了,我没有尝试是否可以,因为微信支付也会主进程中调用
    这个时候就需要处理WxPayEntryActivityStoreWebActivity之间的跨进程通信问题

    1. 跨进程通信的方案有很多,可以参考这篇文章传送,我也是参考这篇文章中的方案解决--使用Messenger解决跨进程通信
    2. 创建一个和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();
        }
    }
    
    1. 然后修改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();
        }
    }
    

    相关文章

      网友评论

          本文标题:WebView内存泄露与跨进程通信

          本文链接:https://www.haomeiwen.com/subject/cwyuixtx.html