0

崩溃日志:

    java.lang.SecurityException: No permission to modify given thread
android.os.Process.setThreadPriority(Native Method)
android.webkit.WebViewCore$WebCoreThread$1.handleMessage(WebViewCore.java:764)
android.os.Handler.dispatchMessage(Handler.java:99)
android.os.Looper.loop(Looper.java:137)
android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.java:829)
java.lang.Thread.run(Thread.java:856)

我应该声明哪个权限? http://developer.android.com/reference/android/Manifest.permission.html

编辑:

我在 WebView java.lang.SecurityException 中发现了一个类似的问题:没有修改给定线程的权限

答案说“这是氰的错”。

但是,在线程http://code.google.com/p/cyanogenmod/issues/detail?id=5656&thanks=5656&ts=1341224425中,cm menbers 似乎否认这是 CM 的错误

最重要的是,我的问题是: 如何从我的应用程序中修复它?

4

2 回答 2

0

我应该声明哪个权限?</p>

此 AFAIK 没有相关许可。不幸的是,实现setThreadPriority()是在本机代码中,这让我很难弄清楚发生了什么。

cm menbers 似乎否认这是 CM 的错误

不,他们没有。没有人发布证据表明这是 CM9 或更高版本中的问题,这就是他们将问题标记为过时的原因。如果您在 CM9 或更高版本上看到此问题,我建议您更新问题。如果您在标准 Android 上看到此问题,请创建一个可以重现该错误的示例项目。

如何从我的应用程序修复它?

你没有,很可能。您可以尝试在您的 上运行一些实验WebView,看看是否有某些特定内容触发了此异常,并尝试修改或消除该内容。

于 2012-11-06T13:14:32.040 回答
0

我从我的应用程序(严重依赖于 webview)中得到了几十个由这个异常引起的崩溃日志,涉及的 ROM 版本是 4.0.4 和 4.0.3。

似乎没有正常的方法来修复它,所以我尝试了以下黑客方法。

4.0.4 上的代码片段:

private static Handler sWebCoreHandler;
// Class for providing Handler creation inside the WebCore thread.
private static class WebCoreThread implements Runnable {
    // Message id for initializing a new WebViewCore.
    private static final int INITIALIZE = 0;
    private static final int REDUCE_PRIORITY = 1;
    private static final int RESUME_PRIORITY = 2;

    public void run() {
        Looper.prepare();
        Assert.assertNull(sWebCoreHandler);
        synchronized (WebViewCore.class) {
            sWebCoreHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    // ...
                    // Process.setPriority(...)
                }
            };
        // ...
        }
        // ...
    }
}

我认为这个异常是从 sWebCoreHandler.handleMessage() 抛出的,如果我们可以在 handleMessage() 上包装 try/catch,问题就可以解决。

Handler 类有四个成员:

final MessageQueue mQueue;
final Looper mLooper;
final Callback mCallback;
IMessenger mMessenger;

mQueue 设置为 mLooper.mQueue,sWebCoreHandler 中的 mCallback 为 null,所以我们只需在 sWebCoreHandler 中设置 mLooper 和 mMessenger 的值。

static Handler sProxyHandler = null;

static void tryTweakWebCoreHandler() {
    // 4.0.3/4.0.4 rom
    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
        tweakWebCoreHandle();
    }
}

static private void tweakWebCoreHandle() {
    if (sProxyHandler != null)
        return;
    try {
        Field f = Class.forName("android.webkit.WebViewCore").getDeclaredField("sWebCoreHandler");
        f.setAccessible(true);
        Object h = f.get(null);
        Object mMessenger = null;
        Method m = Handler.class.getDeclaredMethod("getIMessenger", (Class<?>[])null);
        m.setAccessible(true);
        mMessenger = m.invoke(h, (Object[])null);
        sProxyHandler = new WebCoreProxyHandler((Handler)h);
        if (mMessenger != null) {
            Field f1 = Handler.class.getDeclaredField("mMessenger");
            f1.setAccessible(true);
            f1.set(sProxyHandler, mMessenger);
        }
        f.set(null, sProxyHandler);
        // Log.w(TAG,  "sWebCoreHandler: " + h);
    } catch (Throwable e) {
        Log.w(TAG, "exception: " + e);
    }
    if (sProxyHandler == null)
        sProxyHandler = new Handler();
}

static class WebCoreProxyHandler extends Handler {
    final Handler handler;
    public WebCoreProxyHandler(Handler handler) {
        super(handler.getLooper());
        this.handler = handler;
    }

    public void handleMessage(Message msg) {
        // Log.w("WebCoreProxyHandler", "handle msg: " + msg.what);
        try {
            handler.handleMessage(msg);
        } catch (Throwable tr) {
            Log.w("WebCoreProxyHandler", "exception: " + tr);
        }
    }
}

剩下的问题是何时调用 tryTweakWebCoreHandler()。我尝试在某些设备上创建并测试 WebView 实例后调用它,可以调用 WebCoreProxyHandler.handleMessage()。

注意:我只是做了一些简单的测试,我不确定这个问题是否得到解决,因为原始异常无法可靠地重现。

如果您决定尝试这种方法,请进行足够的测试。

于 2013-06-21T03:22:07.553 回答