android 4.4 webview 内存溢出

我在开发的时候使用webview,在android4.4环境下,第一次进入webview正常,但是到第二次或第三次的时候就会崩溃了。
报错为:

A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.。 java.lang.Throwable: Explicit termination method close not called

初步定为是内存泄露,但是不知道应该怎么回收,在哪儿回收?请大神赐教。

代码如下:

@SuppressLint{ "SetJavaScriptEnabled", "JavascriptInterface" }
public class WebViewActivity extends InstrumentedActivity{ /*************************************************************/ private IWXAPI api; private WebView webView; private ProgressBar loadingProgress;
// private ImageView sbtn;
// private TextView address; public LocationClient mLocationClient = null; private ValueCallback<Uri> mUploadMessage; public static String SHARE_IMAGE_PATH; public BDLocationListener myListener = new MyLocationListener; InitJPushApplication application; String url = null; String path = null; String pathName = null; // 图片路径 String fileName = null; //图片名称 String subFolder = null; String username = null; String password = null; String imageUri = null; String imagePath = null; String rUrl = null; //支付宝订单支付成功后返回的页面地址 int maxWidth,maxHeight; String subject = null; String body = null; String gPrice = null; String orderNo = null; String notifyUrl = null; private final Handler loginHandler = new Handler{ @Override public void handleMessageMessage msg { Intent intent = getIntent; Bundle bundle = intent.getBundleExtra"bundle"; int id = bundle.getInt"id"; String pushUrl = bundle.getString"pushUrl"; //推送过来的URL application = InitJPushApplication getApplication; switch id { case R.id.market: url = Constant.URL_PATH+"/m/"; break; case R.id.recharge: url = Constant.URL_PATH+"/m/member_recharge.html"; break; case R.id.order: url = Constant.URL_PATH+"/m/member_order.html"; break; case R.id.mybaihong: url = Constant.URL_PATH+"/m/member_index.html"; break; case R.id.prefecture: url = Constant.URL_PATH+"/m/brand.html"; break; case R.id.friday: url = Constant.URL_PATH+"/m/seckill.html"; break; case R.id.register: url = Constant.URL_PATH+"/m/register.html"; break; case R.id.forgetpw: url = Constant.URL_PATH+"/m/findpassword.html"; break; case Constant.PUSH_ID: url = pushUrl; break; default: url = Constant.URL_PATH+"/m/"; break; } ifmsg.what==200 { List<String> cookies = List<String> msg.obj; ifcookies!=null { syncCookieToWebViewcookies; webView.loadUrlurl; } }else ifmsg.what==300{ syncCookieToWebViewnull; webView.loadUrlurl; }else{ super.handleMessagemsg; } } }; private Handler payHandler = new Handler { public void handleMessageMessage msg { switch msg.what { case PaymentUtil.SDK_PAY_FLAG: { PayResult payResult = new PayResultString msg.obj; // 支付宝返回此次支付结果及加签,建议对支付宝签名信息拿签约时支付宝提供的公钥做验签 String resultInfo = payResult.getResult; String resultStatus = payResult.getResultStatus; // 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档 if TextUtils.equalsresultStatus, "9000" { Toast.makeTextWebViewActivity.this, "支付成功", Toast.LENGTH_SHORT.show; webView.loadUrlrUrl; } else { // 判断resultStatus 为非“9000”则代表可能支付失败 // “8000”代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态) if TextUtils.equalsresultStatus, "8000" { Toast.makeTextWebViewActivity.this, "支付结果确认中", Toast.LENGTH_SHORT.show; } else { // 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误 Toast.makeTextWebViewActivity.this, "支付失败", Toast.LENGTH_SHORT.show; } } break; } default: break; } }; }; @Override protected void onCreateBundle savedInstanceState { super.onCreatesavedInstanceState; this.getWindow.requestFeatureWindow.FEATURE_NO_TITLE; ShareSDK.initSDKthis; //shareSdk 初始化 setContentViewR.layout.web; initWebView; setWebView; } private void initWebView { webView = WebView findViewByIdR.id.wv;// 获取控件 loadingProgress = ProgressBarfindViewByIdR.id.progressBar;
// address = TextViewsuper.findViewByIdR.id.address;
// sbtn = ImageView findViewByIdR.id.shareButton; //定位 start mLocationClient = new LocationClientgetApplicationContext; //声明LocationClient类 mLocationClient.registerLocationListenermyListener; //注册监听函数 setLocationOption; //设置参数
// mLocationClient.start;// 开始定位 暂时关闭,用不上 //定位end //分享 ---注释掉,html页面添加分享按钮,暂时用不到app上添加按钮
// sbtn.setOnClickListenernew OnClickListener {
// // public void onClickView v {
// // 調用分享方法
// String url = webView.getUrl;
// showShareurl;
// }
// }; new Thread { public void run { initImagePath; } }.start; } public void setWebView{ webView.getSettings.setJavaScriptEnabledtrue;// 是否允许加载js文件 webView.getSettings.setCacheModeWebSettings.LOAD_DEFAULT;// 打开缓存 webView.getSettings.setRenderPriorityRenderPriority.HIGH; webView.getSettings.setDomStorageEnabledtrue; webView.getSettings.setDatabaseEnabledtrue; webView.getSettings.setAllowFileAccesstrue; webView.getSettings.setAppCacheEnabledfalse; String cacheDirPath = getFilesDir.getAbsolutePath+Constant.APP_CACAHE_DIRNAME; webView.getSettings.setDatabasePathcacheDirPath; //设置数据库缓存路径 webView.getSettings.setAppCachePathcacheDirPath; //设置application caches 缓存目录 SharedPreferences settings = getSharedPreferencesConstant.PREFS_NAME, Activity.MODE_PRIVATE; final String Token = settings.getString"LOGIN_INFO", "noToken"; new LoginThreadloginHandler,Token.start; webView.setWebViewClientnew WebViewClient { /** * 重写shouldOverrideUrlLoading,返回值若为true则用webview,false则是系统自身浏览器 */ @Override public boolean shouldOverrideUrlLoadingWebView view, String url { if url.startsWith"tel:" { Intent intent = new IntentIntent.ACTION_VIEW, Uri.parseurl; startActivityintent; } else{ view.loadUrlurl; } return true; } }; webView.addJavascriptInterfacenew Object{ @SuppressWarnings"unused" public String startShareString wxtitle,String wxdesc,String wxlink,String wximgurl throws IOException{ showSharewxlink,wxtitle,wxdesc,wximgurl; return "baihongshare"; } @SuppressWarnings"unused" public String loginString uname,String pwd throws IOException{ username = uname; password = pwd; dologin; return "baihongshare"; } @SuppressWarnings"unused" public String logout throws IOException{ SharedPreferences settings = getSharedPreferencesConstant.PREFS_NAME, Activity.MODE_PRIVATE; SharedPreferences.Editor editor = settings.edit; editor.clear; editor.commit; startActivitynew IntentgetApplication, BaihongMainActivity.class; WebViewActivity.this.finish; return "baihongshare"; } @SuppressWarnings"unused" public String upLoadImageint width,int height,String uploadPath throws IOException{ maxWidth = width; maxHeight = height; subFolder = uploadPath; Intent intent = new IntentIntent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI; startActivityForResultintent, Constant.IMAGECHOOSER_RESULTCODE; return "baihongshare"; } @SuppressWarnings"unused" public String upLoadFileString uploadPath throws IOException{ subFolder = uploadPath; Intent intent = new IntentIntent.ACTION_GET_CONTENT; intent.addCategoryIntent.CATEGORY_OPENABLE; intent.setType"file/*"; WebViewActivity.this.startActivityForResult Intent.createChooserintent, "完成操作需要使用", Constant.FILECHOOSER_RESULTCODE; return "baihongshare"; } /** * @param alipayInterface * H5 页面调用 支付宝支付功能 * @throws IOException */ @SuppressWarnings"unused" public String alipayInterfaceString subject,String body,String gPrice,String orderNo,String notifyUrl,String returnUrl throws IOException{ rUrl = returnUrl; alipaysubject,body,gPrice,orderNo,notifyUrl; return "baihongshare"; } /** * @param alipayInterface * H5 页面调用 微信支付功能 * @throws IOException */ @SuppressWarnings"unused" public String wxpayInterfaceString subject,String body,String gPrice,String orderNo,String notifyUrl,String returnUrl throws IOException{ rUrl = returnUrl; wxpaysubject,body,gPrice,orderNo,notifyUrl; return "baihongshare"; } }, "baihongshare"; webView.setWebChromeClientnew WebChromeClient{ @SuppressWarnings"static-access" public void onProgressChangedWebView view ,int progress{ WebViewActivity.this.setProgressprogress * 100; super.onProgressChangedview, progress; ifprogress != 100{ loadingProgress.setVisibilityview.VISIBLE; loadingProgress.setProgressprogress; } if progress == 100 { loadingProgress.setVisibilityview.GONE; } } /***************** android中使用WebView来打开本机的文件选择器 *************************/ // js上传文件的<input type="file" name="fileField" id="fileField" />事件捕获 // Android < 3.0 调用这个方法 @SuppressWarnings"unused" public void openFileChooserValueCallback<Uri> uploadMsg { mUploadMessage = uploadMsg; Intent intent = new IntentIntent.ACTION_GET_CONTENT; intent.addCategoryIntent.CATEGORY_OPENABLE; intent.setType"image/*"; WebViewActivity.this.startActivityForResult Intent.createChooserintent, "完成操作需要使用", Constant.IMAGECHOOSER_RESULTCODE_NOFILE; } // 3.0 + 调用这个方法 @SuppressWarnings"unused" public void openFileChooserValueCallback<Uri> uploadMsg, String acceptType { mUploadMessage = uploadMsg; Intent intent = new IntentIntent.ACTION_GET_CONTENT; intent.addCategoryIntent.CATEGORY_OPENABLE; intent.setType"image/*"; WebViewActivity.this.startActivityForResult Intent.createChooserintent, "完成操作需要使用", Constant.IMAGECHOOSER_RESULTCODE_NOFILE; } // Android > 4.1.1 调用这个方法 @SuppressWarnings"unused" public void openFileChooserValueCallback<Uri> uploadMsg, String acceptType, String capture { mUploadMessage = uploadMsg; Intent intent = new IntentIntent.ACTION_GET_CONTENT; intent.addCategoryIntent.CATEGORY_OPENABLE; intent.setType"image/*"; WebViewActivity.this.startActivityForResult Intent.createChooserintent, "完成操作需要使用", Constant.IMAGECHOOSER_RESULTCODE_NOFILE; } /************** end ***************/ @Override public boolean onJsAlertWebView webView, String url,String message, JsResult result{ Log.e"onJsAlert","onJsAlert" + message; Toast.makeTextgetApplicationContext, message, Toast.LENGTH_SHORT.show; result.confirm; return true; } @Override public boolean onJsConfirmWebView webView,String url,String message, JsResult result{ Log.e"onJsConfirm", "onJsConfirm"+message; return super.onJsConfirmwebView,url,message,result; } @Override public boolean onJsPromptWebView webView, String url,String message,String defaultValue,JsPromptResult result{ Log.e"onJsPrompt", "onJsPrompt"+url; return super.onJsPromptwebView, url, message, defaultValue, result; } }; } /** * cookie同步 */ private void syncCookieToWebViewList<String> cookies { CookieSyncManager.createInstanceWebViewActivity.this; CookieManager cm = CookieManager.getInstance; cm.setAcceptCookietrue; ifcookies!=null { for String cookie : cookies { cm.setCookieConstant.URL_PATH,cookie;//注意端口号和域名,这种方式可以同步所有cookie,包括sessionid } } CookieSyncManager.getInstance.sync; } //把图片从drawable复制到sdcard中 private void initImagePath { try { if Environment.MEDIA_MOUNTED.equalsEnvironment.getExternalStorageState && Environment.getExternalStorageDirectory.exists { SHARE_IMAGE_PATH = Environment.getExternalStorageDirectory.getAbsolutePath + Constant.FILE_NAME; } else { SHARE_IMAGE_PATH = getApplication.getFilesDir.getAbsolutePath + Constant.FILE_NAME; } File file = new FileSHARE_IMAGE_PATH; if !file.exists { file.createNewFile; Bitmap pic = BitmapFactory.decodeResourcegetResources, R.drawable.icon; FileOutputStream fos = new FileOutputStreamfile; pic.compressCompressFormat.JPEG, 100, fos; fos.flush; fos.close; } } catchThrowable t { t.printStackTrace; SHARE_IMAGE_PATH = null; } } @Override protected void onActivityResultint requestCode, int resultCode, Intent data { super.onActivityResultrequestCode, resultCode, data; if requestCode == Constant.IMAGECHOOSER_RESULTCODE_NOFILE { if null == mUploadMessage return; Uri result = data == null || resultCode != RESULT_OK ? null : data.getData; mUploadMessage.onReceiveValueresult; mUploadMessage = null; }else if requestCode == Constant.IMAGECHOOSER_RESULTCODE { ifdata != null{ Uri uri = data.getData; ifuri != null { String[] pojo = {MediaStore.Images.Media.DATA}; Cursor cursor = getContentResolver.queryuri, pojo, null, null, null; ifcursor != null{ int columnIndex = cursor.getColumnIndexOrThrowpojo[0]; //获得index cursor.moveToFirst; //移动到最前面 path = cursor.getStringcolumnIndex; cursor.close; } ifpath != null{ fileName = path.substringpath.lastIndexOf"/" + 1, path.length; // 判断文件类型 String allowTYpe = "gif,jpg,bmp,png,jpeg"; if !path.trim.equals"" && path.length > 0 { String ex = path.substringpath.lastIndexOf"." + 1, path.length; if allowTYpe.toString.indexOfex < 0 { Toast.makeTextthis, "只能上传gif,jpg,bmp,png格式的图片", Toast.LENGTH_SHORT.show; return; } } // pathName = path; try { new Threadnew Runnable { @Override public void run { try { pathName = BitmapUtils.getThumbUploadPathpath,maxWidth,maxHeight; doUpload; } catch Exception e { e.printStackTrace; } } }.start; } catch Exception e { e.printStackTrace; } } } }else{ webView.loadUrl"javascript:initPicPath,"; } }else ifrequestCode == Constant.FILECHOOSER_RESULTCODE{ // Get the Uri of the selected file ifnull != data{ Uri uri = data.getData; // String path = getPaththis, uri; // String path = ""; if"content".equalsIgnoreCaseuri.getScheme{ String[] pojo = {"_data"}; Cursor cursor = null; try { cursor = this.getContentResolver.queryuri, pojo,null, null, null; int column_index = cursor.getColumnIndexOrThrow"_data"; if cursor.moveToFirst { path = cursor.getStringcolumn_index; } } catch Exception e { // TODO: handle exception } } else if "file".equalsIgnoreCaseuri.getScheme { path = uri.getPath; } ifpath != null{ fileName = path.substringpath.lastIndexOf"/" + 1, path.length; // 判断文件类型 String allowTYpe = "gif,jpg,bmp,swf,png,rar,doc,docx,xls,xlsx,pdf,zip,ico,txt"; if !path.trim.equals"" && path.length > 0 { String ex = path.substringpath.lastIndexOf"." + 1, path.length; if allowTYpe.toString.indexOfex < 0 { Toast.makeTextthis, "不支持此格式文件上传", Toast.LENGTH_SHORT.show; return; } } try { new Threadnew Runnable { @Override public void run { try { pathName = path; doUpload; } catch Exception e { e.printStackTrace; } } }.start; } catch Exception e { e.printStackTrace; } } }else { webView.loadUrl"javascript:initPicPath,"; } } } private void doUpload{ new Threadnew Runnable { @Override public void run { try { InputStream in = new FileInputStreampathName; Map<String,String> data = new HashMap<String,String>; data.put"subFolder", subFolder; String result = UploadUtil.UploadImagein, data,fileName; ifnull != result && !"".equalsresult{ JSONObject json = new JSONObjectEncryptionUtil.decoderesult; String resultMsg = json.getString"result"; if"1".equalsresultMsg{ imageUri = json.getString"imageUri"; imagePath = json.getString"imagePath"; runOnUiThreadnew Runnable { @Override public void run { Log.i"PATH",imageUri; webView.loadUrl"javascript:initPicPath"+imagePath+","+imageUri+""; Toast.makeTextWebViewActivity.this, "上传成功", Toast.LENGTH_SHORT.show; } }; // 判断文件类型 String allowTYpe = "gif,jpg,bmp,png"; if !pathName.trim.equals"" && pathName.length > 0 { String ex = pathName.substringpathName.lastIndexOf"." + 1, pathName.length; if allowTYpe.toString.indexOfex < 0 { }else{ File file = new FilepathName; iffile.exists{ file.delete; } } } }else{ Log.e"pic", resultMsg; runOnUiThreadnew Runnable { @Override public void run { Toast.makeTextWebViewActivity.this, "上传失败", Toast.LENGTH_SHORT.show; } }; } }else{ runOnUiThreadnew Runnable { @Override public void run { Toast.makeTextWebViewActivity.this, "上传失败", Toast.LENGTH_SHORT.show; } }; } } catch Exception e { runOnUiThreadnew Runnable { @Override public void run { Toast.makeTextWebViewActivity.this, "上传失败", Toast.LENGTH_SHORT.show; } }; e.printStackTrace; System.out.printe; } } }.start; } private void dologin{ new Threadnew Runnable { @Override public void run { String regID = JPushInterface.getRegistrationIDgetApplication; String loginkey = EncryptionUtil.encode"{"username":""+username+"","password":""+password+"","regID":""+regID+""," + ""appType":""+Constant.APP_TYPE+"","bizType":""+Constant.BIZ_TYPE+""}"; String url = Constant.URL_PATH+"/widget"; String params = "type=member_login&ajax=yes&action=remotelogin&loginkey="+loginkey; String resultBeforeDecode = HttpUtil.doPosturl, params, "utf-8"; ifresultBeforeDecode.equals"timeout"{ runOnUiThreadnew Runnable { @Override public void run { Toast.makeTextWebViewActivity.this, "请求超市,请稍后重试", Toast.LENGTH_SHORT.show; } }; return; } String resultMsg = EncryptionUtil.decoderesultBeforeDecode; Gson gson = new Gson; User user = gson.fromJsonresultMsg, User.class; ifuser.getResult.equals"1"{ String Token = EncryptionUtil.encode"{"username":""+user.getUsername+"","password":""+user.getPassword+"","regID":""+user.getRegID+"","appType":""+Constant.APP_TYPE+"","bizType":""+Constant.BIZ_TYPE+""}"; SharedPreferences settings = getSharedPreferencesConstant.PREFS_NAME, Activity.MODE_PRIVATE; SharedPreferences.Editor editor = settings.edit; editor.putString"LOGIN_INFO", Token; editor.putString"USER_INFO", resultMsg; editor.commit; } } }.start; } /** * 支付宝支付 * @param gName 商品名称 * @param gDesc 商品描述 * @param gPrice 商品价格 * @param orderNo 订单号 */ public void alipayString subject,String body,String gPrice,String orderNo,String notifyUrl{ // 订单 String orderInfo = PaymentUtil.getOrderInfosubject,body,gPrice,orderNo,notifyUrl; // 对订单做RSA 签名 String sign = PaymentUtil.signorderInfo; try { // 仅需对sign 做URL编码 sign = URLEncoder.encodesign, "UTF-8"; } catch UnsupportedEncodingException e { e.printStackTrace; } // 完整的符合支付宝参数规范的订单信息 final String payInfo = orderInfo + "&sign="" + sign + ""&" + PaymentUtil.getSignType; Runnable payRunnable = new Runnable { @Override public void run { // 构造PayTask 对象 PayTask alipay = new PayTaskWebViewActivity.this; // 调用支付接口,获取支付结果 String result = alipay.paypayInfo; Message msg = new Message; msg.what = PaymentUtil.SDK_PAY_FLAG; msg.obj = result; payHandler.sendMessagemsg; } }; // 必须异步调用 Thread payThread = new ThreadpayRunnable; payThread.start; } /** * 支付宝支付 * @param gName 商品名称 * @param gDesc 商品描述 * @param gPrice 商品价格 * @param orderNo 订单号 */ public void wxpayString subject,String body,String gPrice,String orderNo,String notifyUrl{ api = WXAPIFactory.createWXAPIthis, Constant.APP_ID; api.registerAppConstant.APP_ID; this.subject = subject; this.body = body; this.gPrice = gPrice; this.orderNo = orderNo; this.notifyUrl = notifyUrl; new GetAccessTokenTask.execute; } private void setLocationOption { LocationClientOption option = new LocationClientOption; option.setOpenGpstrue; option.setIsNeedAddresstrue; // 返回的定位结果包含地址信息 option.setAddrType"all"; // 返回的定位结果包含地址信息 option.setCoorType"bd09ll"; // 返回的定位结果是百度经纬度,默认值gcj02 option.setScanSpan5000; // 设置发起定位请求的间隔时间为5000ms mLocationClient.setLocOptionoption; } public class MyLocationListener implements BDLocationListener { public void onReceiveLocationBDLocation location { if location == null return; StringBuffer sb = new StringBuffer256; if location.getLocType == BDLocation.TypeNetWorkLocation { //sb.append"当前位置 : "; //sb.appendlocation.getAddrStr; //sb.appendlocation.getCity; sb.appendlocation.getDistrict; sb.appendlocation.getStreet; sb.appendlocation.getStreetNumber; } //address.setTextsb.toString; } public void onReceivePoiBDLocation poiLocation { } } @Override public boolean onKeyDownint keyCode, KeyEvent event {// keyCode代表按键的数字标示符 Intent intent = getIntent; Bundle bundle = intent.getBundleExtra"bundle"; String key = bundle.getString"key"; if keyCode == KeyEvent.KEYCODE_BACK { if webView.canGoBack { webView.goBack; return true; } else if null != key && key.equals"webview" { intent.setClassWebViewActivity.this, BaihongMainActivity.class; startActivityintent; WebViewActivity.this.finish; }else { System.exit0; } } return super.onKeyDownkeyCode, event; } //share 调用OneKeyShare private void showShareString wxlink, String wxtitle, String wxdesc, String wximgurl { OnekeyShare oks = new OnekeyShare; //关闭sso授权 oks.disableSSOWhenAuthorize; //分享时Notification的图标和文字 ,Notification是一种状态栏的提示 oks.setNotificationR.drawable.icon, getStringR.string.app_name; // title标题,印象笔记、邮箱、信息、微信、人人网和QQ空间使用 oks.setTitlewxtitle; // titleUrl是标题的网络链接,仅在人人网和QQ空间使用 oks.setTitleUrlwxlink; // text是分享文本,所有平台都需要这个字段 oks.setTextwxdesc+":"+wxlink; // imagePath是图片的本地路径,Linked-In以外的平台都支持此参数 //oks.setImagePathWebViewActivity.TEST_IMAGE;//确保SDcard下面存在此张图片 oks.setImageUrlwximgurl; // url仅在微信(包括好友和朋友圈)中使用 oks.setUrlwxlink; // comment是我对这条分享的评论,仅在人人网和QQ空间使用 oks.setCommentwxdesc; // site是分享此内容的网站名称,仅在QQ空间使用 oks.setSitegetStringR.string.baihong_portal; // siteUrl是分享此内容的网站地址,仅在QQ空间使用 oks.setSiteUrlwxlink; // 启动分享GUI oks.showthis; } @Override protected void onDestroy { super.onDestroy; mLocationClient.stop;// 停止定位 ShareSDK.stopSDK; webView.clearHistory; webView.clearCachetrue; } private class GetAccessTokenTask extends AsyncTask<Void, Void, GetAccessTokenResult> { private ProgressDialog dialog; @Override protected void onPreExecute { } @Override protected void onPostExecuteGetAccessTokenResult result { if dialog != null { dialog.dismiss; } if result.localRetCode == LocalRetCode.ERR_OK { Log.d"wxpay-getToken", "onPostExecute, accessToken = " + result.accessToken; GetPrepayIdTask getPrepayId = new GetPrepayIdTaskresult.accessToken; getPrepayId.execute; } } @Override protected GetAccessTokenResult doInBackgroundVoid... params { GetAccessTokenResult result = new GetAccessTokenResult; String url = String.format"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", Constant.APP_ID, Constant.APP_SECRET; Log.d"wxpay-GetAccessTokenResult", "get access token, url = " + url; byte[] buf = WxPayUtil.httpGeturl; if buf == null || buf.length == 0 { result.localRetCode = LocalRetCode.ERR_HTTP; return result; } String content = new Stringbuf; result.parseFromcontent; return result; } } private class GetPrepayIdTask extends AsyncTask<Void, Void, GetPrepayIdResult> { private ProgressDialog dialog; private String accessToken; public GetPrepayIdTaskString accessToken { this.accessToken = accessToken; } @Override protected void onPreExecute { } @Override protected void onPostExecuteGetPrepayIdResult result { if dialog != null { dialog.dismiss; } if result.localRetCode == LocalRetCode.ERR_OK { sendPayReqresult; } } @Override protected void onCancelled { super.onCancelled; } @Override protected GetPrepayIdResult doInBackgroundVoid... params { String url = String.format"https://api.weixin.qq.com/pay/genprepay?access_token=%s", accessToken; String entity = genProductArgs; Log.d"wxpay-GetPrepayIdResult", "doInBackground, url = " + url; Log.d"wxpay-GetPrepayIdResult", "doInBackground, entity = " + entity; GetPrepayIdResult result = new GetPrepayIdResult; byte[] buf = WxPayUtil.httpPosturl, entity; if buf == null || buf.length == 0 { result.localRetCode = LocalRetCode.ERR_HTTP; return result; } String content = new Stringbuf; Log.d"wxpay-GetPrepayIdResult", "doInBackground, content = " + content; result.parseFromcontent; return result; } } private static enum LocalRetCode { ERR_OK, ERR_HTTP, ERR_JSON, ERR_OTHER } private static class GetAccessTokenResult { private static final String TAG = "MicroMsg.SDKSample.PayActivity.GetAccessTokenResult"; public LocalRetCode localRetCode = LocalRetCode.ERR_OTHER; public String accessToken; public int expiresIn; public int errCode; public String errMsg; public void parseFromString content { if content == null || content.length <= 0 { Log.eTAG, "parseFrom fail, content is null"; localRetCode = LocalRetCode.ERR_JSON; return; } try { JSONObject json = new JSONObjectcontent; if json.has"access_token" { // success case accessToken = json.getString"access_token"; expiresIn = json.getInt"expires_in"; localRetCode = LocalRetCode.ERR_OK; } else { errCode = json.getInt"errcode"; errMsg = json.getString"errmsg"; localRetCode = LocalRetCode.ERR_JSON; } } catch Exception e { localRetCode = LocalRetCode.ERR_JSON; } } } private static class GetPrepayIdResult { private static final String TAG = "MicroMsg.SDKSample.PayActivity.GetPrepayIdResult"; public LocalRetCode localRetCode = LocalRetCode.ERR_OTHER; public String prepayId; public int errCode; public String errMsg; public void parseFromString content { if content == null || content.length <= 0 { Log.eTAG, "parseFrom fail, content is null"; localRetCode = LocalRetCode.ERR_JSON; return; } try { JSONObject json = new JSONObjectcontent; if json.has"prepayid" { // success case prepayId = json.getString"prepayid"; localRetCode = LocalRetCode.ERR_OK; } else { localRetCode = LocalRetCode.ERR_JSON; } errCode = json.getInt"errcode"; errMsg = json.getString"errmsg"; } catch Exception e { localRetCode = LocalRetCode.ERR_JSON; } } } private String genNonceStr { Random random = new Random; return MD5.getMessageDigestString.valueOfrandom.nextInt10000.getBytes; } private long genTimeStamp { return System.currentTimeMillis / 1000; } /** * 建议 traceid 字段包含用户信息及订单信息,方便后续对订单状态的查询和跟踪 */ private String getTraceId { return "crestxu_" + genTimeStamp; } private long timeStamp; private String nonceStr, packageValue; private String genSignList<NameValuePair> params { StringBuilder sb = new StringBuilder; int i = 0; for ; i < params.size - 1; i++ { sb.appendparams.geti.getName; sb.append=; sb.appendparams.geti.getValue; sb.append&; } sb.appendparams.geti.getName; sb.append=; sb.appendparams.geti.getValue; String sha1 = WxPayUtil.sha1sb.toString; Log.d"wxpay-genOutTradNo", "genSign, sha1 = " + sha1; return sha1; } private String genPackageList<NameValuePair> params { StringBuilder sb = new StringBuilder; for int i = 0; i < params.size; i++ { sb.appendparams.geti.getName; sb.append=; sb.appendparams.geti.getValue; sb.append&; } sb.append"key="; sb.appendConstant.PARTNER_KEY; // 注意:不能hardcode在客户端,建议genPackage这个过程都由服务器端完成 // 进行md5摘要前,params内容为原始内容,未经过url encode处理 String packageSign = MD5.getMessageDigestsb.toString.getBytes.toUpperCase; return URLEncodedUtils.formatparams, "utf-8" + "&sign=" + packageSign; } private String genProductArgs { JSONObject json = new JSONObject; try { json.put"appid", Constant.APP_ID; String traceId = getTraceId; // traceId 由开发者自定义,可用于订单的查询与跟踪,建议根据支付用户信息生成此id json.put"traceid", traceId; nonceStr = genNonceStr; json.put"noncestr", nonceStr; List<NameValuePair> packageParams = new LinkedList<NameValuePair>; packageParams.addnew BasicNameValuePair"bank_type", "WX"; packageParams.addnew BasicNameValuePair"body", body; packageParams.addnew BasicNameValuePair"fee_type", "1"; packageParams.addnew BasicNameValuePair"input_charset", "UTF-8"; packageParams.addnew BasicNameValuePair"notify_url", notifyUrl; packageParams.addnew BasicNameValuePair"out_trade_no", orderNo; packageParams.addnew BasicNameValuePair"partner", Constant.PARTNER_ID; packageParams.addnew BasicNameValuePair"spbill_create_ip", getLocalIpAddress; packageParams.addnew BasicNameValuePair"total_fee", gPrice; packageValue = genPackagepackageParams; json.put"package", packageValue; timeStamp = genTimeStamp; json.put"timestamp", timeStamp; List<NameValuePair> signParams = new LinkedList<NameValuePair>; signParams.addnew BasicNameValuePair"appid", Constant.APP_ID; signParams.addnew BasicNameValuePair"appkey", Constant.APP_KEY; signParams.addnew BasicNameValuePair"noncestr", nonceStr; signParams.addnew BasicNameValuePair"package", packageValue; signParams.addnew BasicNameValuePair"timestamp", String.valueOftimeStamp; signParams.addnew BasicNameValuePair"traceid", traceId; json.put"app_signature", genSignsignParams; json.put"sign_method", "sha1"; } catch Exception e { Log.e"wxpay-genProductArgs", "genProductArgs fail, ex = " + e.getMessage; return null; } return json.toString; } private void sendPayReqGetPrepayIdResult result { PayReq req = new PayReq; req.appId = Constant.APP_ID; req.partnerId = Constant.PARTNER_ID; req.prepayId = result.prepayId; req.nonceStr = nonceStr; req.timeStamp = String.valueOftimeStamp; req.packageValue = "Sign=" + packageValue; List<NameValuePair> signParams = new LinkedList<NameValuePair>; signParams.addnew BasicNameValuePair"appid", req.appId; signParams.addnew BasicNameValuePair"appkey", Constant.APP_KEY; signParams.addnew BasicNameValuePair"noncestr", req.nonceStr; signParams.addnew BasicNameValuePair"package", req.packageValue; signParams.addnew BasicNameValuePair"partnerid", req.partnerId; signParams.addnew BasicNameValuePair"prepayid", req.prepayId; signParams.addnew BasicNameValuePair"timestamp", req.timeStamp; req.sign = genSignsignParams; // 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信 api.sendReqreq; } @Override protected void onNewIntentIntent intent { super.onNewIntentintent; setIntentintent; } /** *获得客户端真实IP地址的方法 * @return */ public String getLocalIpAddress { String ip = ""; ConnectivityManager connectMgr = ConnectivityManager this.getSystemServiceContext.CONNECTIVITY_SERVICE; NetworkInfo info = connectMgr.getActiveNetworkInfo; ifinfo != null{ ifinfo.getType == ConnectivityManager.TYPE_WIFI{ WifiManager wifiManager = WifiManager getSystemServiceContext.WIFI_SERVICE; //判断wifi是否开启 if !wifiManager.isWifiEnabled { wifiManager.setWifiEnabledtrue; } WifiInfo wifiInfo = wifiManager.getConnectionInfo; int ipAddress = wifiInfo.getIpAddress; ip = formatIpAddressipAddress; return ip; }else ifinfo.getType == ConnectivityManager.TYPE_MOBILE{ try { for Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces; en.hasMoreElements; { NetworkInterface intf = en.nextElement; for Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses; enumIpAddr.hasMoreElements; { InetAddress inetAddress = enumIpAddr.nextElement; if !inetAddress.isLoopbackAddress { ip = inetAddress.getHostAddress.toString; } } } } catch SocketException ex { Log.e"getLocalIpAddress", ex.toString; } } }else { ip = "127.0.0.1"; } return ip; } private static String formatIpAddressint ipAdress { return ipAdress & 0xFF + "." + ipAdress >> 8 & 0xFF + "." + ipAdress >> 16 & 0xFF + "." + ipAdress >> 24 & 0xFF ; } }

扫了一遍代码,有可能是因为这个泄露了。

InputStream in = new FileInputStreampathName;

应该在 finally 里面关闭。

try { InputStream in = new FileInputStreampathName; //...
} finally { if in != null { in.close; }
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注