在 Android BroadcastReceiver 中使用 Jsoup 时如何解决 "UnsatisfiedLinkError"?

How to solve "UnsatisfiedLinkError" while using Jsoup in an Android BroadcastReceiver?

我在做什么:

我的应用程序(Android和minSdkVersion 15)中,我有一个BroadcastReceiverIntent.ACTION_PACKAGE_ADDED(A新的应用程序包已安装在设备上)。每当发生这种情况时,接收方都会尝试使用 Jsoup.

从互联网上获取一些数据

问题:

只要 我的应用程序 在我安装另一个应用程序(比如来自 Play 商店)时在后台 运行,我下面的代码就可以正常工作。但是,如果我终止 我的应用程序 然后安装另一个应用程序,我的应用程序 会崩溃并显示 "My app has stopped" 对话框(因为我的接收器崩溃了)以及这个错误:

No implementation found for long com.android.tools.profiler.support.network.HttpTracker$Connection.nextId() (tried Java_com_android_tools_profiler_support_network_HttpTracker_00024Connection_nextId and Java_com_android_tools_profiler_support_network_HttpTracker_00024Connection_nextId__)
FATAL EXCEPTION: AsyncTask #1
Process: com.myorg.myapp, PID: 11796
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask.done(AsyncTask.java:325)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:243)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.UnsatisfiedLinkError: No implementation found for long com.android.tools.profiler.support.network.HttpTracker$Connection.nextId() (tried Java_com_android_tools_profiler_support_network_HttpTracker_00024Connection_nextId and Java_com_android_tools_profiler_support_network_HttpTracker_00024Connection_nextId__)
    at com.android.tools.profiler.support.network.HttpTracker$Connection.nextId(Native Method)
    at com.android.tools.profiler.support.network.HttpTracker$Connection.<init>(HttpTracker.java:191)
    at com.android.tools.profiler.support.network.HttpTracker$Connection.<init>(HttpTracker.java:186)
    at com.android.tools.profiler.support.network.HttpTracker.trackConnection(HttpTracker.java:280)
    at com.android.tools.profiler.support.network.httpurl.TrackedHttpURLConnection.<init>(TrackedHttpURLConnection.java:49)
    at com.android.tools.profiler.support.network.httpurl.HttpsURLConnection$.<init>(HttpsURLConnection$.java:50)
    at com.android.tools.profiler.support.network.httpurl.HttpURLWrapper.wrapURLConnectionHelper(HttpURLWrapper.java:40)
    at com.android.tools.profiler.support.network.httpurl.HttpURLWrapper.wrapURLConnection(HttpURLWrapper.java:55)
    at org.jsoup.helper.HttpConnection$Response.createConnection(HttpConnection.java:889)
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:727)
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:706)
    at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:299)
    at org.jsoup.helper.HttpConnection.get(HttpConnection.java:288)
    at com.myorg.myapp.InstallReceiver$PlayStoreFetcher.doInBackground(InstallReceiver.java:76)
    at com.myorg.myapp.InstallReceiver$PlayStoreFetcher.doInBackground(InstallReceiver.java:70)
    at android.os.AsyncTask.call(AsyncTask.java:305)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:243) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:761)

我的代码:

InstallReceiver.java:

public class InstallReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {
            String data = new FetchData().execute("URL").get();

            // The rest of my code...
        }
    }

    private static class FetchData extends AsyncTask<String, Integer, String> {    
        @Override
        protected String doInBackground(String... strings) {
            try {
                // This is the cause of the problem
                return Jsoup.connect(strings[0]).get().text();
            } catch (Exception e) {
                return null;
            }
        }
    }
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.myorg.myapp">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".Activities.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".Activities.PlayStoreActivity"/>
        <activity android:name=".Activities.InstalledAppsActivity"/>
        <activity android:name=".Activities.PredefinedFiltersActivity"/>

        // This is linking my InstallReceiver.java
        <receiver android:name=".InstallReceiver">
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <data android:scheme="package" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

build.gradle:

dependencies {
    compile 'org.jsoup:jsoup:1.11.2'

    // The rest of my dependencies...
}

我的尝试:

  1. 我用一般的 catch (Exception e) 语句包围了 Jsoup 调用,但错误仍然存​​在。
  2. 我查看了这个错误并找到了一些答案,例如 and this one,但其中 none 似乎解决了我的问题。
  3. 我将 Jsoup 调用移动到 IntentService 并从我的 InstallReceiver 启动了该服务,但仍然抛出相同的错误(从服务)。
  4. 尝试使用 (new URL(url)).openConnection() 获取 HTML 并得到相同的错误,但现在它说的不是 Jsoup 因为 URLConnection
  5. 使用 Thread class 而不是 AsyncTask,但仍然出现相同的错误。

我的尝试暗示该错误与 Jsoup 并没有真正相关,它与当应用程序不是 运行 时从接收器连接到互联网有关!

我猜测当 我的应用程序 不是 运行 时,此 HttpTracker$Connection.nextId() 存在导入问题。

知道如何解决这个问题吗?

当您尝试读取不存在的 dll/so 文件时,通常会发生这种情况。
由于您所做的非常标准,问题可能出在 android 工作室而不是您的代码上。
要解决它 - 只需将最小 sdk 提高到 20(或更多)。 (高级网络分析器崩溃,这是因为它在版本 20 下不受支持)。