每一个总结都是个人遇到或者看资料时发现的点,说的比较简单。其中一些基础的知识还需读者去自行了解,这里的每一条总结可能都会随着版本的更新而无效,大家了解即可,每一篇总结25条。
1.
不能在onPause中做过多复杂的操作,因为必须onPause执行完成以后新Activity才能Resume。
2.
onSaveInstanceState是在Activity被异常终止的情况下才会调用,正常情况下是不会调用的。它的调用时机是onStop之前,与onPause没有先后顺序关系。它会把存贮的Bundle数据传给onRestoreInstanceState和onCreate两个方法,而onRestoreInstanceState方法则会在onStart之后调用。系统会自动给我们保存一些当前Activity的视图结构,比如文本框中的文字等。
3.
和Activity一样,View也有onSaveInstanceState和onRestoreInstanceState两个方法。
4.
通过修改AndroidManifest.xml文件里Activity的configChanges可以避免某些情况下系统重建Activity,比如旋转屏幕等,但是它会调用onConfigurationChanged的方法。
5.启动模式的特殊点
模式 | 备注 |
---|---|
standard 标准模式 | 谁启动了具有该模式的Activity,该Activity就在谁的栈里。当ApplicationContext启动该模式的Activity时需要指定FLAG_ACTIVITY_NEW_TASK标记,这时候这个Activity是以singleTask的模式启动的 |
singleTop 栈顶复用模式 | 启动该模式的Activity在栈顶时虽然不会被重新创建,但是会调用它的onNewIntent方法 |
singleTask 栈内复用模式 | 启动该模式的Activity在栈内时不会被重新创建,和singleTop一样,会调用它的onNewIntent方法。重点:当栈内的Activity为ABCD时,在当前栈启动该模式的Activity B时B之上的Activity会全部出栈,栈内只剩下AB |
singleInstance 单实例模式 | 这个模式只需说明一个使用情况就可以了解,比如开发一个任务提醒的App,需要到某个时间弹出一个Activity来提醒用户。用户那个时间点在浏览微信,使用这个模式,弹出Activity之后用户点返回就会重新退回刚刚微信的界面,如果是标准模式则会进入你的App,显然是不符合逻辑的 |
6.设置启动模式的两个方法和区别
方法 | 区别 |
---|---|
AndroidManifest | 优先级低,无法为Activity设置FLAG_ACTIVITY_CLAER_TOP(销毁目标Activity和它之上的所有Activity,重新创建目标Activity) |
intent.addFlags | 优先级高,无法为Activity指定singleInstance模式 |
7.build.gradle
外层的build.gradle
buildscript {
repositories {
jcenter()
//这个是代码托管库,用于托管代码
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
//这里是gradle的引用,版本号为2.3.3,这是用来构建安卓项目的,
//当然了,Java、C++它也可以构建
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
内层(APP下)的build.gradle
//这里有两个plugin可选
//1.com.android.application 2.com.android.library
//1.可以直接运行 2.只能依附于别的引用程序模块运行
apply plugin: 'com.android.application'
android {
compileSdkVersion 27 //这个是项目的sdk版本号
buildToolsVersion "28.0.2" //这个是构建项目的工具的版本
defaultConfig {
applicationId "pjk.it.bjfu.buildgradle" //项目的包的名称
minSdkVersion 24 //最低兼容的安卓版本号
targetSdkVersion 27 //你的程序在哪个版本上进行开发的,
//所有的功能在此版本上应该都是兼容的
versionCode 1 //项目的版本号
versionName "pjk_1.0" //项目的版本号对应的版本名
//以上两个属性非常重要,是应用商店判断应用有更新的重要依据
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//用于测试的工具
}
buildTypes {
release {
minifyEnabled false
//是否对项目的代码进行混淆 true是 false否
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//混淆用的文件
}
//通常会有debug和release两个闭包,顾名思义,是用来测试和线上发布的不同配置
}
}
//依赖库,大致有本地依赖(jar包)、远程依赖、和库依赖
//compile fileTree本地依赖、compile远程依赖、compile project(':helper')库依赖
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support.constraint:constraint-layout:1.0.2'
//远程依赖在gradle的时候如果本地没有缓存,就会链接互联网下载,所以编译的时候需要网速好
testCompile 'junit:junit:4.12'
//测试用例的依赖
}
8、使用setAgruments从Activity向Fragment发送信息
使用方法
Activity中:
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putString("something_key", "something_value");
fragment.setArguments(bundle);
Fragment中:
onCreateView{
Bundle bundle = getArguments();
String something = bundle.getString("something_key");
}
这样就在创建的时候将activity中的数据传递给fragment了,是不是很简单。
9、日志的查看
日志名称 | 对应级别 | 重要程度 | 备注说明 |
---|---|---|---|
Log.v() | verbose | ★ | 意义比较小的日志,一般不用 |
Log.d() | debug | ★★ | 打印调试的信息,调试用这个 |
Log.i() | info | ★★★ | 打印一些数据,比如请求的数据,用户输入的数据等 |
Log.w() | warm | ★★★★ | 打印警告信息,最好修复一下带有warm的信息 |
Log.e() | error | ★★★★★ | 错误信息,程序遇到这样的bug会崩溃,必须修复 |
如下图所示,就算你不打印日志,也会出现运行时的日志的,你选择重要程度低的日志时,会自动显示它和它重要程度以上的日志信息,例如你的程序崩溃了,你就选择Error就行,先解决重要的bug。
10、Context在Android中的作用
什么是Context
Context在Android中,可以认为是当前对象在程序中所处的一个环境,一个与系统交互的过程。
Context到底是什么呢?一个Activity就是一个Context,一个Service也是一个Context。Android程序员把“场景”抽象为Context类,他们认为用户和操作系统的每一次交互都是一个场景。可以认为是一个展示View控件和各种服务的平台或者镜头。
获得Context的方法
一般用以下两种方法来获取Context
getApplication()方法只有在Activity和Service中才能调用的到。
如果在一些其它的场景,比如BroadcastReceiver中也想获得Application的实例,这时就可以借助getApplicationContext()方法了。
11、修饰符的注意点
修饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | Y/N | N |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |
子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。
protected 访问修饰符可以修饰类及其方法和成员变量,但是接口及接口的成员变量和成员方法不能声明为 protected。
请注意以下方法继承的规则:
-
父类中声明为 public 的方法在子类中也必须为 public。
-
父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
-
父类中声明为 private 的方法,不能够被继承。
12.启动Service的不同周期
使用startService()
使用bindService()
同时使用startService()和bindService()
13、RecycleView下拉刷新
嵌套SwipeRefreshLayout
文件相关:
XML文件
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v4.widget.SwipeRefreshLayout>
Activity文件:
swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
//TODO
}
});
这样就在下拉的时候就可以执行相关语句刷新RecyclerView