You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 19:01:20