【问题标题】:Leaked window exception even though no service is used即使没有使用服务,也会出现泄漏的窗口异常
【发布时间】:2013-08-04 00:55:45
【问题描述】:

我遇到了一个非常奇怪的问题。

我的 logcat 中不断出现这种崩溃,但奇怪的是我的应用与 Text To Speech 无关。不只是这个活动,我的整个应用根本不使用它。

08-04 03:47:19.321: E/ActivityThread(24755): Activity com.lablabla.similarsearch.WebViewActivity has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@443065c0 that was originally bound here
08-04 03:47:19.321: E/ActivityThread(24755): android.app.ServiceConnectionLeaked: Activity com.lablabla.similarsearch.WebViewActivity has leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@443065c0 that was originally bound here
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:974)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:868)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.ContextImpl.bindServiceAsUser(ContextImpl.java:1452)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.ContextImpl.bindService(ContextImpl.java:1440)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.content.ContextWrapper.bindService(ContextWrapper.java:496)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.speech.tts.TextToSpeech.connectToEngine(TextToSpeech.java:685)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.speech.tts.TextToSpeech.initTts(TextToSpeech.java:655)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.speech.tts.TextToSpeech.<init>(TextToSpeech.java:608)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.webkit.AccessibilityInjector$TextToSpeechWrapper.<init>(AccessibilityInjector.java:682)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.webkit.AccessibilityInjector.addTtsApis(AccessibilityInjector.java:483)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.webkit.AccessibilityInjector.addAccessibilityApisIfNecessary(AccessibilityInjector.java:168)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.webkit.AccessibilityInjector.updateJavaScriptEnabled(AccessibilityInjector.java:418)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.webkit.WebViewClassic.updateJavaScriptEnabled(WebViewClassic.java:1682)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.webkit.WebSettingsClassic.setJavaScriptEnabled(WebSettingsClassic.java:1125)
08-04 03:47:19.321: E/ActivityThread(24755):    at com.lablabla.similarsearch.WebViewActivity.onCreate(WebViewActivity.java:24)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.Activity.performCreate(Activity.java:5133)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.ActivityThread.access$600(ActivityThread.java:141)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.os.Looper.loop(Looper.java:137)
08-04 03:47:19.321: E/ActivityThread(24755):    at android.app.ActivityThread.main(ActivityThread.java:5103)
08-04 03:47:19.321: E/ActivityThread(24755):    at java.lang.reflect.Method.invokeNative(Native Method)
08-04 03:47:19.321: E/ActivityThread(24755):    at java.lang.reflect.Method.invoke(Method.java:525)
08-04 03:47:19.321: E/ActivityThread(24755):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
08-04 03:47:19.321: E/ActivityThread(24755):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-04 03:47:19.321: E/ActivityThread(24755):    at dalvik.system.NativeStart.main(Native Method)

这是该活动的代码:(它所做的只是从Intent 获取一个网址并将其加载到WebView

public class WebViewActivity extends Activity {

    public static final String EXTRA_URL = "extra_url";

    private WebView webView;
    private String baseUrl;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webview);
        webView = (WebView) findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebViewClient(new WebViewClient());
        webView.getSettings().setUserAgentString(
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/20 Safari/537.31");
        baseUrl = getIntent().getStringExtra(EXTRA_URL);
        webView.loadUrl(baseUrl);
    }
}

【问题讨论】:

  • 你知道这是什么吗?在使用 TalkBack 测试我的应用时,我看到了同样的情况。当我点击后退按钮退出我的一项活动时,TalkBack 会发出相同的错误。我的活动也有一个启用了 javascript 的 webview。我的活动没有主动使用 TTS 服务。我只是在测试它与 TalkBack 的配合情况。我在 Google Groups 上找到了一个讨论相同问题的帖子,但显然它神奇地自行解决了。 groups.google.com/forum/#!topic/eyes-free/b_3OJI8h4tQ
  • 我没有。它似乎不会影响它本身的应用程序,我找不到任何迹象表明它会导致影响手机正常功能的其他应用程序或服务出现任何问题。我刚刚开始为此提供赏金,也许它会以这种方式解决。

标签: java android service


【解决方案1】:

我的 logcat 中不断出现这种崩溃,但奇怪的是我的 app 与 Text To Speech 无关。不只是这个 活动,我的整个应用根本不使用它。

您的应用确实与它无关。

除了你打电话时:

webView.getSettings().setJavaScriptEnabled(true);

方法 WebViewClassic.updateJavaScriptEnabled(boolean) 被执行:

void updateJavaScriptEnabled(boolean enabled) {
    if (isAccessibilityInjectionEnabled()) {

 ==>>>> // Call placed to AccessibilityInjector.updateJavaScriptEnabled(boolean)
        getAccessibilityInjector().updateJavaScriptEnabled(enabled);
    }
}

在这里,isAccessibilityInjectionEnabled() 在您设备的情况下返回 true。它检索当前启用的无障碍服务列表,并提供/支持AccessibilityServiceInfo.FEEDBACK_SPOKEN。如果此列表非空,则返回 true

向上移动堆栈跟踪:

android.webkit.AccessibilityInjector.addTtsApis()

最终创建一个TextToSpeech 对象。

问题:TextToSpeech.connectToEngine() 使用 Context 调用 bindService()。上下文是您的 Activity 的上下文(从 WebView 传递)。我相信当WebViewActivity 启动时,Logcat 会显示这个(或类似的):

成功绑定到 com.google.android.tts

假设:当您的 Activity 被销毁并在屏幕旋转时重新创建时,TTS 服务仍然被绑定,而上下文不再有效。这就是异常所指的。

我尝试了以下方法来检验我的假设:

我没有在 xml 中定义 WebView,而是在 onCreate() 中动态创建它:

webView = new WebView(getApplicationContext());

请注意,我使用应用程序的上下文代替了 Activity 的(this)。上下文在方向更改时保持有效,因此不会引发异常。

要确认一个(或多个)无障碍服务已启用,请将此代码添加到您的活动的 onCreate():

AccessibilityManager am = (AccessibilityManager)
                                   getSystemService(ACCESSIBILITY_SERVICE);

List<AccessibilityServiceInfo> listOfServices = 
                                 am.getEnabledAccessibilityServiceList(
                                   AccessibilityServiceInfo.FEEDBACK_ALL_MASK);

for (AccessibilityServiceInfo asi : listOfServices) {
    Log.i("", "Accessibility Service >>>>>>>>: " + asi.getSettingsActivityName());
Log.i("", "Accessibility Service >>>>>>>>: " +
                                 asi.loadDescription(getPackageManager()));

}

注意:我必须打开 TalkBack(在“设置”>“辅助功能”下)才能重现该问题。另外,我不确定为什么在强制停止应用程序后没有抛出这个异常。

基于用户 Robert Nekic 的评论:后按时的行为:使用活动的上下文时会引发异常。应用程序的上下文仍然有效。

有用信息:Link

【讨论】:

  • 在 Android 4.4 上启用 Talkback 时,我收到 AccessibilityInjector 的 logcat 错误。您能否在此处建议解决此问题的任何方法:stackoverflow.com/q/29434063/1263215
  • webview = (WebView) findViewById(R.id.webview_wv);我通过查找得到了webview,那么我该如何避免这个异常呢?
  • @thecr0w 我发现使用Application 上下文是规避此异常的唯一方法。明显的副作用是您无法在 xml 中定义 WebView。您必须在运行时创建它并将其添加到您的布局中。您可以尝试一件事:在 xml 中定义您的 WebView 并使用通过 LayoutInflater.fromContext(getApplicationContext()) 获得的 LayoutInflater 扩展该布局。我不能说它是否会起作用。
【解决方案2】:

你可以添加这段代码sn-p来避免这个服务连接泄露异常:

class YourActivity extends Activity {
WebView yourWebView;

    @Override
    public void onDestroy() {

        if (yourWebView != null) {
            yourWebView.getSettings().setJavaScriptEnabled(false);
        }
}

yourWebView.getSettings().setJavaScriptEnabled(false);将触发 AccessibilityInjector.updateJavaScriptEnabled() 的调用 其中:

private void removeTtsApis() {
    if (mTextToSpeech != null) {
        mTextToSpeech.stop();
        mTextToSpeech.shutdown();
        mTextToSpeech = null;
    }

    mWebView.removeJavascriptInterface(ALIAS_TTS_JS_INTERFACE);
}

mTextToSpeech.shutdown() 只是关键。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    • 2016-06-29
    • 2021-11-19
    • 1970-01-01
    • 2015-03-04
    相关资源
    最近更新 更多