文档章节

Windows环境下Android Studio系列8—SDK版本配置

一配
 一配
发布于 2015/09/08 11:36
字数 1398
阅读 205
收藏 0

1. 问题的由来

在一次调试问题中,出现下面错误信息:

09-07 09:15:08.000    1342-1342/? W/System.err﹕ android.os.NetworkOnMainThreadException
09-07 09:15:08.000    1342-1342/? W/System.err﹕ at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)
09-07 09:15:08.000    1342-1342/? W/System.err﹕ at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
09-07 09:15:08.000    1342-1342/? W/System.err﹕ at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
09-07 09:15:08.000    1342-1342/? W/System.err﹕ at java.net.InetAddress.getByName(InetAddress.java:289)
略。。。。。。

后来百度/Google"android.os.NetworkOnMainThreadException", [1]中在2013-06-24的博文中就指出:NetworkOnMainThreadException是因为应用程序在主线程上尝试网络操作。另外,这个异常在Honeycomb SDK或更高版本的SDK上才会抛出。低版本的SDK允许应用程序在主线程或loop线程执行网络操作,但不鼓励这样做。应该放到子线程中,然后当子线程完成之后再发广播也好,message也好,通知主线程做相应的UI更改,或利用AsyncTask来做网络操作。

这个问题涉及到AndroidManifest.xml文件中的SDK版本配置,而且随着Android Studio缺省使用Gradle来编译,build.gradle文件中也存在相应的SDK版本配置,那么如何来正确地配置这些SDK版本呢?

2. AndroidManifest.xml文件中的minSdkVersion与targetSdkVersion

参考[2], AndroidManifest.xml文件中,<uses-sdk>标签中有minSdkVersion, targetSdkVersion, maxSdkVersion三个属性,由于maxSdkVersion属性已经不再推荐配置,因此下面主要讨论另外两个属性。

首先minSdkVersion与targetSdkVersion都是整数值,通常都需要配置而不要采用默认值。

minSdkVersion是应用程序运行所需的SDK最低版本。如果不指明该属性,其默认值为1。如果Android手机版本低于这个值,应用程序将安装失败。


[3]中通过查看Android源码和两个例子来理解targetSdkVersion

例子1: DatePickerDialog组件

当AndroidManifest.xml文件中 targetSDKversion属性设置不同的值,DatePickerDialog组件表现会不同。如果设置的值为10或更低的值,DatePickerDialog为左侧显示。如果设置的值为11或更高的值,DatePickerDialog为右侧显示。

DatePickerDialog look with targetSDKversion 10 or lower DatePickerDialog look with targetSDKversion 11 or higher

Android源码如下(注意:下面代码可能在最新的SDK版本中有变化,但判断targetSdkVersion的逻辑没变):

public DatePickerDialog(Context context,
    OnDateSetListener callBack,
    int year,
    int monthOfYear,
    int dayOfMonth,
    boolean yearOptional) {
        this(context, context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB                
                ? com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert
                : com.android.internal.R.style.Theme_Dialog_Alert,
        callBack, year, monthOfYear, dayOfMonth, yearOptional);
}

在第7行根据设置的targetSDKversion来设置不同的theme:getApplicationInfo().targetSdkVersion >= SOME_VERSION。实际上在Android源码中到处都有类似的判断

例子2Webview类

当设置 targetSDKversion属性为18或更高值时,Webview类的public方法应当在主线程中调用,否则运行时系统将抛出一个RuntimeException。可参见下面源代码:

sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
            Build.VERSION_CODES.JELLY_BEAN_MR2;
    
if (sEnforceThreadChecking) {
    throw new RuntimeException(throwable);
}

Android官方文档中提到, 随着Android新版本的发展,一些行为甚至appearances 可能发生改变从前面两个例子已经可以看出。

总结一下:当设置targetSdkVersion为更高的值时,就像DatePickerDialog例子中那样会有appearance增强的好处,但正如Webview例子那样,以前在低版本中正常运行的代码,如果修改targetSdkVersion为更高时可能会引发致命错误,但此时在开发阶段就可以修订代码来适应更高的targetSdkVersion因此targetSdkVersion属性告诉系统该应用已经在target Version系统上进行了充分测试。

但可能targetSdkVersion这个SDK版本中的某个新特性在低版本中是不支持的,那么在低版本的API设备上运行程序时,可能会报错:java.lang.VerifyError。也就是说,此属性不会帮你解决兼容性的测试问题。你至少需要在minSdkVersion这个版本上将程序完整的跑一遍来确定兼容性是没有问题的。

因此,需要在minSdkVersion与targetSdkVersion分别需要将程序完整的跑一遍来确保兼容性没有问题。

3. build.gradle中的SDK版本配置 

build.gradle中会有以下代码:

android {
        compileSdkVersion 19
        buildToolsVersion "21.1.1"
     
        defaultConfig {
            minSdkVersion 8
            targetSdkVersion 19
        }

AndroidManifest.xml文件中有以下代码:

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="8"/>

Gradle文件会覆盖manifest文件中的值,可以不用管mainfest文件中的值,将minSdkVersion和targetSdkVersion都在Gradle文件中配置即可,也可以删除mainfest文件中的<uses-sdk>标签。


在build.gradle文件中,

compileSdkVersion是编译时Android的API level。

buildToolsVersion是编译器(aapt, dx, renderscript compiler等)的版本. 从版本18开始的每个API level, 会有一个匹配的.0.0编译器版本。例如在IO 2014, 发布了API 20和build-tools 20.0.0。

minSdkVersion与targetSdkVersion在前面已经讨论过。

注意:targetSdkVersion不应当超过compileSdkVersion。


在[4]中还给出了一种统一各个版本的方法:

编辑 gradle.properties 文件,增加以下代码:

ANDROID_BUILD_MIN_SDK_VERSION=14
ANDROID_BUILD_TARGET_SDK_VERSION=21
ANDROID_BUILD_TOOLS_VERSION=21.1.3
ANDROID_BUILD_SDK_VERSION=21

然后,就可以在 build.gradle 文件中这样使用:

//...android {
    compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
    buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION

    defaultConfig {
        minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
        targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
    }
}//..

4. 遗留问题 

在build.gradle文件中,除了上述与版本相关的配置以外,在dependencies中也涉及编译期间的版本配置,这留待后续再学习研究:

dependencies {
    compile 'com.android.support:support-v4:20.0.0'
    
    // your unit test dependencies as described in the article
    unitTestCompile files("$project.buildDir/classes/release")
    unitTestCompile 'junit:junit:4.11'
    unitTestCompile 'com.google.android:android:4.1.1.4'
    unitTestCompile 'org.robolectric:robolectric:2.1.1'

    // duplicate these dependencies in the instrumentTestCompile scope 
    // in order to have the integration in Android Studio (autocompletion and stuff)
    instrumentTestCompile 'junit:junit:4.11'
    instrumentTestCompile 'org.robolectric:robolectric:2.1.1'
}


5. 参考资料

[1] android.os.NetworkOnMainThreadException的解决方案, 2013-06-24, http://www.cnblogs.com/kissazi2/archive/2013/06/24/3153307.html

[2] Android中<uses-sdk>属性和target属性分析, 2014-06-03, http://blog.csdn.net/fuzhengchao/article/details/28121193

[3] Android Min SDK Version vs. Target SDK Version, http://stackoverflow.com/questions/4568267/android-min-sdk-version-vs-target-sdk-version

[4] How do I add a library project to the Android Studio?http://stackoverflow.com/questions/16588064/how-do-i-add-a-library-project-to-the-android-studio/16639227#16639227

© 著作权归作者所有

一配
粉丝 34
博文 144
码字总数 112398
作品 0
西城
私信 提问
Windows环境下Android Studio系列2—初次运行

参考资料 [1] Windows环境下Android Studio v1.0安装教程, http://ask.android-studio.org/?/article/9 [2] stormZhang的Android Studio系列教程一--下载与安装, http://stormzhang.com/dev......

一配
2015/06/17
830
0
Windows环境下Android Studio系列1—下载与安装

参考资料 [1] Windows环境下Android Studio v1.0安装教程, http://ask.android-studio.org/?/article/9 [2] stormZhang的Android Studio系列教程一--下载与安装, http://stormzhang.com/dev......

一配
2015/06/16
1K
0
Flutter基础(二)Flutter开发环境搭建和Hello World

本文首发于公众号「刘望舒」 关联系列 ReactNative入门系列 React Native组件 Flutter基础系列 前言 其实没想写Flutter的相关文章的,因为这些看官方文档就够了,但是有不少同学就想看我写的...

刘望舒
08/19
0
0
Android开发学习总结(二)——使用Android Studio搭建Android集成开发环境

一、Android Studio简单介绍   2013年GoogleI/O大会首次发布了Android Studio IDE(Android平台集成开发环境)。它基于Intellij IDEA开发环境,旨在取代Eclipse和ADT(Android开发者工具)...

哒哒成晨
05/14
13
0
Flutter基础(二)Flutter最新开发环境搭建和Hello World

本文首发于微信公众号「刘望舒」 前言 最近的Google I/O大会上,Flutter1.5 预览版开始支持移动、Web、桌面和嵌入式设备,从不温不火的sky一直进化到如今热门的Flutter,Flutter的发展已经超...

刘望舒
05/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
今天
6
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
今天
6
0
【技术分享】TestFlight测试的流程文档

上架基本需求资料 1、苹果开发者账号(如还没账号先申请-苹果开发者账号申请教程) 2、开发好的APP 通过本篇教程,可以学习到ios证书申请和打包ipa上传到appstoreconnect.apple.com进行TestF...

qtb999
今天
10
0
再见 Spring Boot 1.X,Spring Boot 2.X 走向舞台中心

2019年8月6日,Spring 官方在其博客宣布,Spring Boot 1.x 停止维护,Spring Boot 1.x 生命周期正式结束。 其实早在2018年7月30号,Spring 官方就已经在博客进行过预告,Spring Boot 1.X 将维...

Java技术剑
今天
17
0
浅谈java过滤器Filter

一、简介 Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断如是否有权限访问页面等。其工作原理是,只要你在web.xml...

青衣霓裳
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部