解决Cordova插件中调用close方法无法关闭新Activity的问题
Cordova插件关闭新Activity无响应问题解决
当前你的close方法实现存在错误:this.cordova.getActivity().finish()关闭的是Cordova的主Activity(承载WebView的核心Activity),而非你通过open方法启动的NewActivity,因此调用AbrirHTML.close()没有任何反应。
以下是两种可行的修复方案:
方案一:通过广播机制关闭NewActivity(推荐,无内存泄漏风险)
1. 修改NewActivity.java,添加广播接收器
package com.actionsistemas.abrirhtml; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.util.Log; import android.webkit.WebSettings; import android.webkit.WebView; public class NewActivity extends Activity { // 定义广播Action常量 public static final String ACTION_CLOSE_NEW_ACTIVITY = "com.actionsistemas.abrirhtml.CLOSE_NEW_ACTIVITY"; private BroadcastReceiver closeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String package_name = getApplication().getPackageName(); Intent intent = getIntent(); String html = intent.getStringExtra("url"); Log.e("*** HTML ***", html); setContentView(getApplication().getResources().getIdentifier("activity_new", "layout", package_name)); WebView webView = (WebView) findViewById(getApplication().getResources().getIdentifier("web1", "id", package_name)); WebSettings settings = webView.getSettings(); settings.setSupportMultipleWindows(true); settings.setJavaScriptCanOpenWindowsAutomatically(false); settings.setAllowFileAccessFromFileURLs(true); settings.setAllowUniversalAccessFromFileURLs(true); settings.setJavaScriptEnabled(true); settings.setDomStorageEnabled(true); settings.setCacheMode(2); webView.clearCache(true); webView.setBackgroundColor(0); webView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null); webView.loadUrl(html); // 注册广播接收器 closeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (ACTION_CLOSE_NEW_ACTIVITY.equals(intent.getAction())) { finish(); // 关闭当前Activity } } }; IntentFilter filter = new IntentFilter(ACTION_CLOSE_NEW_ACTIVITY); registerReceiver(closeReceiver, filter); } @Override public void onDestroy() { super.onDestroy(); String package_name = getApplication().getPackageName(); WebView webView = (WebView) findViewById(getApplication().getResources().getIdentifier("web1", "id", package_name)); webView.destroy(); // 注销广播接收器,避免内存泄漏 if (closeReceiver != null) { unregisterReceiver(closeReceiver); } } }
2. 修改AbrirHTML.java的closeNewActivity方法,发送关闭广播
package com.actionsistemas.abrirhtml; import android.content.Context; import android.content.Intent; import android.util.Log; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaWebView; import org.apache.cordova.CordovaInterface; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class AbrirHTML extends CordovaPlugin { public void initialize(CordovaInterface cordova, CordovaWebView webView) { super.initialize(cordova, webView); } @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { Context context = cordova.getActivity().getApplicationContext(); if(action.equals("open")) { String url = args.getString(0); Log.e("*** URL ***", url); this.openNewActivity(context, url); callbackContext.success("NewActivity opened"); // 添加回调通知 return true; } else if(action.equals("close")){ this.closeNewActivity(context); callbackContext.success("Close signal sent"); // 添加回调通知 return true; } callbackContext.error("Invalid action"); return false; } private void openNewActivity(Context context, String url) { Intent intent = new Intent(context, NewActivity.class); intent.putExtra("url", url); this.cordova.getActivity().startActivity(intent); } private void closeNewActivity(Context context) { // 发送关闭广播 Intent closeIntent = new Intent(NewActivity.ACTION_CLOSE_NEW_ACTIVITY); context.sendBroadcast(closeIntent); } }
方案二:通过持有Activity实例关闭(适合单实例场景)
1. 修改AbrirHTML.java,添加静态变量保存NewActivity实例
package com.actionsistemas.abrirhtml; import android.content.Context; import android.content.Intent; import android.util.Log; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaWebView; import org.apache.cordova.CordovaInterface; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class AbrirHTML extends CordovaPlugin { // 静态变量持有NewActivity实例 private static NewActivity newActivityInstance; public void initialize(CordovaInterface cordova, CordovaWebView webView) { super.initialize(cordova, webView); } @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { Context context = cordova.getActivity().getApplicationContext(); if(action.equals("open")) { String url = args.getString(0); Log.e("*** URL ***", url); this.openNewActivity(context, url); callbackContext.success("NewActivity opened"); return true; } else if(action.equals("close")){ this.closeNewActivity(); callbackContext.success("NewActivity closed"); return true; } callbackContext.error("Invalid action"); return false; } private void openNewActivity(Context context, String url) { Intent intent = new Intent(context, NewActivity.class); intent.putExtra("url", url); this.cordova.getActivity().startActivity(intent); } private void closeNewActivity() { if (newActivityInstance != null && !newActivityInstance.isFinishing()) { newActivityInstance.finish(); newActivityInstance = null; // 清空引用避免内存泄漏 } } // 提供方法给NewActivity设置实例 public static void setNewActivityInstance(NewActivity instance) { newActivityInstance = instance; } // 提供方法清空实例 public static void clearNewActivityInstance() { newActivityInstance = null; } }
2. 修改NewActivity.java,在生命周期中设置/清空实例
package com.actionsistemas.abrirhtml; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.webkit.WebSettings; import android.webkit.WebView; public class NewActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 设置实例到AbrirHTML AbrirHTML.setNewActivityInstance(this); String package_name = getApplication().getPackageName(); Intent intent = getIntent(); String html = intent.getStringExtra("url"); Log.e("*** HTML ***", html); setContentView(getApplication().getResources().getIdentifier("activity_new", "layout", package_name)); WebView webView = (WebView) findViewById(getApplication().getResources().getIdentifier("web1", "id", package_name)); WebSettings settings = webView.getSettings(); settings.setSupportMultipleWindows(true); settings.setJavaScriptCanOpenWindowsAutomatically(false); settings.setAllowFileAccessFromFileURLs(true); settings.setAllowUniversalAccessFromFileURLs(true); settings.setJavaScriptEnabled(true); settings.setDomStorageEnabled(true); settings.setCacheMode(2); webView.clearCache(true); webView.setBackgroundColor(0); webView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null); webView.loadUrl(html); } @Override public void onDestroy() { super.onDestroy(); String package_name = getApplication().getPackageName(); WebView webView = (WebView) findViewById(getApplication().getResources().getIdentifier("web1", "id", package_name)); webView.destroy(); // 清空实例引用,避免内存泄漏 AbrirHTML.clearNewActivityInstance(); } }
内容的提问来源于stack exchange,提问作者Guilherme Lirio
相关产品推荐
相关产品推荐

