前提条件和构建配置:我正在尝试通过设置下面的AndroidStudio O perview设备的构建配置参数,compileSdkVersion ' Android -O‘buildToolsVersion '25.0.0’compileOptions.encoding = 'ISO-8859-1‘minSdkVersion 16 targetSdkVersion 'O’//启用多索引支持,使用android 2.4版本5构建我的应用。multiDexEnabled true
问题描述:我的应用程序在使用旧版安卓系统的设备上使用以下这些ConnectivityManager类的弃用方法。-ConnectivityManager.startUsingNetworkFeature() - ConnectivityManager.stopUsingNetworkFeature() - ConnectivityManager.requestRouteToHost()
当我尝试构建具有上述api的应用程序时,它给出了如下编译时错误,
错误:(626,48)错误:找不到符号方法startUsingNetworkFeature(int,String)错误:(7393,27)错误:找不到符号方法stopUsingNetworkFeature(int,String)错误:(69,36)错误:找不到符号方法requestRouteToHost(int,int)
理想情况下,出于向后兼容目的,这些api不应该给出编译时错误。请告诉我如何解决这些编译时错误。
我不能从代码中删除这些方法,因为它们是使用较旧android版本(低于Android L版本)的设备所必需的。
发布于 2017-10-17 20:11:35
在你的项目中创建一个新的android库模块。确保这个库有compileSdkVersion 25。然后将以下类放入库中:
@SuppressWarnings("Deprecation")
public class NetworkFeaturesCompat {
public static NetworkFeaturesCompat from(final ConnectivityManager cm) {
return new NetworkFeaturesCompat(cm);
}
private final ConnectivityManager mConnectivityManager;
private NetworkFeaturesCompat(final ConnectivityManager cm) {
mConnectivityManager = cm;
}
public int startUsingNetworkFeature(final int networkType, final String feature) {
return mConnectivityManager.startUsingNetworkFeature(networkType, feature);
}
public int stopUsingNetworkFeature(final int networkType, final String feature) {
return mConnectivityManager.stopUsingNetworkFeature(networkType, feature);
}
public boolean requestRouteToHost(final int networkType, final int hostAddress) {
return mConnectivityManager.requestRouteToHost(networkType, hostAddress);
}
}现在,通过修改它的build.gradle文件,让你的主模块依赖于这个库:
dependencies {
compile project(":your-new-library-module-name")
}构建您的项目。
现在你可以从你的主项目中使用这个助手类了。
您可能需要将此添加到您的proguard规则中(我还没有实际测试过这一点):
-dontwarn android.net.ConnectivityManager请注意,这种方法仍然会在Android 6+上抛出UnsupportedOperationException。
为什么这是可行的?
原来的方法仍然存在于SDK中,它们只是对SDK 26中的公共API隐藏起来。这就是它在运行时不会崩溃的原因。
库模块是针对SDK 25编译的,其中方法仍然是公共API的一部分。这就是它在编译时不会崩溃的原因。
由于整个项目都是在SDK26上编译的,proguard可能会抱怨缺少方法。在这种情况下,忽略投诉就可以了。
发布于 2018-07-03 04:26:44
因为我不能对Antilope的答案添加注释,所以我将在这里更正它。
应该是method.invoke(connectivityManager, ConnectivityManager.TYPE_MOBILE, "enableHIPRI");
因此,通常代码看起来像这样:
try{
java.lang.reflect.Method method = connectivityManager.getClass().getMethod("startUsingNetworkFeature",
int.class, String.class);
resultInt = (int) method.invoke(connectivityManager, ConnectivityManager.TYPE_MOBILE,
"enableHIPRI");
} catch (Exception e) {
//Do something
}和
try{
java.lang.reflect.Method method = connectivityManager.getClass().getMethod("requestRouteToHost", int.class, int.class);
resultBool = (boolean) method.invoke(connectivityManager, ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);
} catch (Exception e) {
//Do something
}上面的代码适用于targetSDK 27
发布于 2018-05-29 21:45:56
正如这些bug报告线程(https://issuetracker.google.com/issues/64992660)所建议的那样,尽管反射可以在以API27为目标的情况下进行调用。在不同的设备上测试,甚至在配备Oreo的Galaxy Note8 (8.0.0)上也是如此。
我之前所说的:
resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");现在可以这样调用:
try{
java.lang.reflect.Method method = connectivityManager.getClass().getMethod("startUsingNetworkFeature",
int.class, String.class); resultInt = (int) method.invoke(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");
} catch (Exception e) {
//Do something
}也适用于:
resultBool = connectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);现在可以这样调用:
try{
java.lang.reflect.Method method = connectivityManager.getClass().getMethod("requestRouteToHost", int.class, int.class);
resultBool = (boolean) method.invoke(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);
} catch (Exception e) {
//Do something
}https://stackoverflow.com/questions/43365391
复制相似问题