We know that Android M has removed support for HttpClient. Apps linking with it will have to explicitly say so: add a library dependency in your gradle file.
But does it break backward compatibility with existing applications?
Suppose I wrote an app which supports Api level 1 and higher and it's never maintained since last year. The targetSdkLevel of the app is certainly lower than 22. Will it crash on Android M? The source code could have been lost.
The answer looks to be yes.
I looked in the Android M source code through the SDK manager, and the package for the client is not in the source.
Package name for the HttpClient:
org.apache.http.client.HttpClient
Existing paths:
org.apache.http.conn
org.apache.http.params
Ways to fix this:
Add this to your build.graddle:
android {
useLibrary 'org.apache.http.legacy'
}
Use OkHttp-UrlConnection as an almost drop in replacement by adding this to your build.graddle:
compile 'com.squareup.okhttp:okhttp-urlconnection:2.4.0'
Example usage:
private static OkHttpClient okHttpClient = new OkHttpClient();
HttpURLConnection urlConnection = new OkUrlFactory(okHttpClient).open(url);
Related
I have imported
implementation 'com.google.android.things:androidthings:1.0'
And when I execute code, it throws a runtime error because inside of the PeripheralManager class the methods are all stubs:
public List<String> getUartDeviceList() {
throw new RuntimeException("Stub!");
}
This was working several months ago, I've tried changing implementation to compile
There are several conditions you should verify in your project:
Your device must be either the i.MX7D or Raspberry Pi 3B with the Android Things OS on it, as noted in the hardware guide.
Your app/build.gradle must use compileOnly 'com.google.android.things:androidthings:1.0'
Your app/src/main/AndroidManifest.xml must include the following as a child of the application element:
<uses-library android:name="com.google.android.things"/>
You may also want to check properties like the targetSdkVersion being 27. If you continue to run into trouble, check out Android Things sample projects.
Which device are you running it into? This API is only available on Android Things boards, not on phones.
I am having com.squareup.okhttp3:okhttp-urlconnection:3.13.1 jar as dependency in gradle file of my Android project and used as below to get the URLConnection.
protected URLConnection getStandardHTTPURLConnection(URL url) throws IOException {
return new OkHttpURLConnection(url, builder.cookieJar(new JavaNetCookieJar(CookieHandler.getDefault())).build());
}
So I updated the jar to 4.9.0 and realized that OkHttpURLConnection is not available. It is leading to noClassDefinition exception in the run time. so what are the alternatives? Is it deprecated or moved under another hood?
Below are my imports.
import okhttp3.internal.huc.OkHttpURLConnection;
import okhttp3.internal.huc.OkHttpsURLConnection;
Kindly advice.
There's a compatibility implementation you can paste in that's mentioned in the OkHttp 3.14.0 release notes.
https://square.github.io/okhttp/changelog_3x/#version-3140
From https://square.github.io/okhttp/changelog_3x/ so I guess they got removed on 4.x
The Apache HTTP client and HttpURLConnection APIs are deprecated. They
continue to work as they always have, but we’re moving everything to
the new OkHttp 3 API. The okhttp-apache and okhttp-urlconnection
modules should be only be used to accelerate a transition to OkHttp’s
request/response API. These deprecated modules will be dropped in an
upcoming OkHttp 3.x release.
I'm trying to migrate some Java library from 'normal' JVM to android and stuck with some Java11 APIs used in the code.
The first thing I already got - Java11 language features seems to work only with Canary build of Android Studio, see answer here
Now I need to get understanding about which APIs can be really used. Here are two use-cases which do not work for me and I can't get if I'm doing something wrong or it never should work:
List.copyOf() - introduced in Java11, method copyOf is not available on android. Methods 'List.of()', introduced with Java 9, work OK.
class java.lang.invoke.LambdaMetafactory - introduced with Java 1.8 - to be used for programmatic creation of lambdas for usage instead for reflection, is not visible on Android.
I see both of them in sources of desugar_jdk_libs here:
https://github.com/google/desugar_jdk_libs/blob/master/jdk11/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java
https://github.com/google/desugar_jdk_libs/blob/master/src/share/classes/java/util/List.java
So - the question is: how can I identify if some Java API is supposed to be available in 'desugared' android build or no? What really can be expected from 'desugaring'?
Steps to reproduce:
Using Android Studio Canary generate a dummy "Basic Activity" project
Make sure following is provided in build.gradle
android {
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}
Add following lines somewhere in code
List<Integer> ints1 = List.of(1, 2, 3);
Supplier<List<Object>> listSupplier = () -> new ArrayList<>();
List<Object> alist = listSupplier.get();
List<Integer> ints2 = List.copyOf(ints1);
LambdaMetafactory.metafactory(null,null,null,null,null,null);
Last 2 lines fail to compile for me.
PS: final application is supposed to work on Android 10+.
Contrary to the other answer, desugaring is totally possible.
The dependency to add is
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}
You can find more information at the official Android Java 8 desugaring documentation.
Desugaring lib is considered unofficial. We can't expect an exact answer. We get the feature when it is ready. Now List.copyOf() method now working with the latest Gradle version.
About the LambdaMetafactory class, It is not included in Android Javadoc. This means we assume we don't have LambdaMetafactory at all. Google stripped down some java API for being lightweight.
In general, We should check android Javadoc first. If android Javadoc has no mention about some API. We can be sure we won't get that feature anytime soon.
How to refer aosp hidden methods in core android app using gradle build system. I am referring framework and other jars from out folder but unable to access hidden API. Is there any way to access hidden methods.
There are a couple ways.
Android Hidden API
As long as you're fine targeting API 27 (there's no API 28 release as of writing this) this way works great. You can directly call the hidden methods with proper code completion and everything.
Note: As of writing this, you'll need to set your Gradle classpath to 3.1.4. 3.2.0 adds some sort of integrity check that breaks builds when using a modified framework JAR.
Use reflection
It's not ideal, but it'll work if you want to target API 28, or you want to use Gradle 3.2.0.
Example (Kotlin):
val IWindowManager = Class.forName("android.view.IWindowManager")
val IWindowManagerStub = Class.forName("android.view.IWindowManager\$Stub")
val ServiceManager = Class.forName("android.os.ServiceManager")
val binder = ServiceManager.getMethod("checkService", String::class.java).invoke(null, Context.WINDOW_SERVICE)
val iWindowManagerInstance = IWindowManagerStub.getMethod("asInterface", Binder::class.java).invoke(null, binder)
val hasNavBar = IWindowManager.getMethod("hasNavigationBar").invoke(iWindowManagerInstance) as Boolean
client.post(AppConfig.getApplicationContext(),
HttpUrls.getUrl()
+ urlroot, new StringEntity(jsonData, "UTF-8"),
"application/json", handler);
I use StringEntity as HttpEntity when I post a request by XHttpClient in Android API 21, but when I use Android API 23, I cannot use it again. I think there should be a class in API 23 which equivalent to the class StringEntity in API 21, so which class can I use?
Support for Apache HTTP Client has been removed from Android 6.0. Check Android 6.0 changes.
Android 6.0 release removes support for the Apache HTTP client. If your app is using this client and targets Android 2.3 (API level 9) or higher, use the HttpURLConnection class instead. This API is more efficient because it reduces network use through transparent compression and response caching, and minimizes power consumption. To continue using the Apache HTTP APIs, you must first declare the following compile-time dependency in your build.gradle file:
android {
useLibrary 'org.apache.http.legacy'
}