How to solve the “UnsatisfiedLinkError” when using Jsoup in Android BroadcastReceiver?
What I’m doing :
In my app (Android minSdkVersion 15
), I have a BroadcastReceiver
listener Intent.ACTION_PACKAGE_ ADDED
(the new application package is already installed on the device). Whenever this happens, the receiver tries to get some data from the internet using Jsoup.
Question:
As long as my app
is running in the background when I install another app, such as from the Play Store, my code below will work. However, if I terminate My Apps and then install another app, My Apps crashes with the “My Apps Stopped” dialog box (because my receiver crashed) along with this error:
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$3.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$1.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$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.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)
My code:
Install the recipient .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...
}
My try:
- I surrounded the Jsoup call with a generic
catch (Exception e)
statement, but the error persisted. - I looked at this error and found some answers like this one and this one, but neither of them seems to solve my problem.
- I move the Jsoup call to
IntentService
and start the service from myInstallReceiver
and still throw the same error (from the service). - Tried fetching HTML using (
new URL(url).openConnection()
and got the same error, but now it says because instead ofJsoup URLConnection
- Use
the Thread
class instead ofAsyncTask
, but still get the same error.
My attempt implies that the bug isn’t really related to Jsoup, it has to do with connecting to the internet from a receiver when the app isn’t running!
I’m guessing there is an import issue with this HttpTracker$Connection.nextId()
when my app isn’t running.
Any idea how to solve this problem?
Solution
This usually happens when you try to read a non-existent dll/so file.
Because what you do is very standard, the problem may be with Android Studio rather than your code.
To solve it – just raise the minimum SDK to 20 (or more).
(Advanced Network Analyzer crashes because it is not supported under version 20).