您的位置:首页 > 移动开发 > Android开发

Android编程权威指南(第2版)读书笔记

2018-01-02 16:46 190 查看
1.按键监听器
在按键监听器注册时匿名内部类中使用toast时注意,此时this是View.OnClickListener,而不是activity
2.有时,出于种种原因,可能需要脱离Android Studio编译代码。

要使用Gradle,请切换到项目目录并执行以下命令:
$ ./gradlew tasks
如果是Windows系统,执行以下命令:
> gradlew.bat tasks
执行以上命令会显示一系列可用任务。你需要的是任务是installDebug,因此,再执行以下
命令:
$ ./gradlew installDebug
如果是Windows系统,执行以下命令。
> gradlew.bat installDebug
以上命令将把应用安装到当前连接的设备上,但不会运行它。要运行应用,需要在设备上手
动启动。
3.设置自动识别前缀
首先,配置Android Studio识别成员变量的m前缀。
打开Android Studio首选项对话框(Mac用户选择Android Studio菜单,Windows用户选择File →
Settings菜单)。分别展开Editor和Code Style选项,在Java选项下选择Code Generation选项页。
在Naming表单中,选择Fields行,添加m作为fields的前缀,然后添加s作为StaticFields的前缀 。
4.控件继承关系
View->TextView->Button
View->ImageView->ImageButton
5.onCreate()方法生命周期相关
通常, activity通过覆盖onCreate(...)方法来准备以下用户界面相关的工作:
 实例化组件并将组件放置在屏幕上(调用setContentView(int)方法);
 引用已实例化的组件;
 为组件设置监听器以处理用户交互;
 访问外部模型数据。
千万不要自己去调用onCreate(...)方法或任何其他Ac
4000
tivity生命周期方法,记住这一点
很重要。我们只需在activity子类里覆盖这些方法,Android会适时去调用它们。 
另外,在onCreate(...)方法里,必须首先调用超类的实现方法,然后再调用
其他方法,这一点很关键。而在其他几个方法中,是否首先调用超类方法就不那么重要了。
需要注意的是,停止的activity能够存在多久,谁也无法保证。系统需要回收内存时,它将首
先销毁那些停止的activity。 
系统重启或长时间不使用activity时,暂存的activity记录通常也会被清除,此时的保存在activity中的bundle中的数据也会消失。
和单击主屏幕键不一样的是,单击后退键后,无论是否启用Don’t keep activities选项,系统
总是会销毁当前activity。单击后退键相当于通知系统“用户不再需要使用当前的activity”

6.设备旋转导致界面回到初始
在应用运行中,只要设备配置发生了改变,Android就会销毁当前activity,然后再
创建新的activity。

设备旋转时,系统会销毁当前QuizActivity实例,然后创建一个新的QuizActivity实例,重新调用oncreate调用新的布局文件。再
次旋转设备,查看该销毁与再创建的过程。

横屏activity的创建:
New → Android resource directory
从资源类型(Resource type)列表中选择layout,保持Source Set的main选项不变。接下来选中待选资源特征列表中的Orientation,然后单击>>按钮将其移动至已选资源特征区域
确认选中Screen Orientation下拉列表中的Landscape选项,并确保目录名显示为layout-land,如图3-10所示。点击OK按钮让Android Studio创建res/layout-land。 
在project视图下,将activity_quiz.xml文件从res/layout目录复制至res/layout-land目录,两个布局文件必须具有相同的文件名,这样它们才能以同一个资源ID被引用。
修改layout-land下的布局文件,修改成framelayout,这个帧布局是使用android:layout_gravity来指定位置,因此每个framelayout的直属子类需要添加这个值
在activity中覆盖onSaveInstanceState,put键值对,在oncreate中获取和设置键值。

7.显式intent
简单的方法是直接在数据目的activity中
Intent i = new Intent(QuizActivity.this, CheatActivity.class);
startActivity(i); 带参数的intent
传递数据需要在数据目的activity加入
public static Intent newIntent(Context packageContext, boolean answerIsTrue) {
Intent i = new Intent(packageContext, CheatActivity.class);
i.putExtra(EXTRA_ANSWER_IS_TRUE, answerIsTrue);
return i;
}
然后在数据源activity中调用这个方法,并且把数据answerIsTrue传递进去
Intent i = CheatActivity.newIntent(QuizActivity.this, answerIsTrue);
startActivityForResult(intent, REQUEST_CODE_CHEAT);
然后就可以在数据目的activity中获取
mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);
处理返回值
发出返回值的activity首先设置数据isAnswerShown
private void setAnswerShownResult(boolean isAnswerShown) {
Intent data = new Intent();
data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown);
setResult(RESULT_OK, data);
}
其次设置静态解析方法
public static boolean wasAnswerShown(Intent result) {
return result.getBooleanExtra(EXTRA_ANSWER_SHOWN, false);
}

接收返回值的activity覆盖onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CODE_CHEAT) {
if (data == null) {
return;
}
mIsCheater = CheatActivity.wasAnswerShown(data);
}
}

8.创建UI fragment
创建UI fragment的步骤与创建activity的步骤相同,具体如下:
 通过定义布局文件中的组件,组装界面;
 创建fragment类并设置其视图为定义的布局;
 通过代码的方式,组装在布局文件中实例化的组件 

9.布局属性
android:padding和android:margin的区别
android:layout_marginLeft指该控件距离边父控件的边距,指定视图组件间的距离;

android:paddingLeft指该控件内部内容,如文本距离该控件的边距。指定视图外边框与其内容间的距离。

如:
当按钮分别设置以上两个属性时,得到的效果是不一样的。
android:paddingLeft="30px":
按钮上设置的内容(例如图片)离按钮左边边界30个像素。
android:layout_marginLeft="30px"
整个按钮离左边设置的内容30个像素
这二个属性是相对的,假设B是A的子控件,设置B的margin和设置A的padding能达到相同的效果。

不以layout_开头的属性作用于组件 
以layout_开头的属性则作用于组件的父组件

10 .日期SimpleDateFormat 

// SimpleDateFormat 类的格式化字符:// G 年代指示符(AD) // y 年(yy:10 y/yyy/yyyy:2010)// M 月(M:1 MM:01 MMM:Jan MMMM:January MMMMM:J) // L 独立月(L:1 LL:01 LLL:Jan LLLL:January LLLLL:J) // d 一个月中的第几日(只需此一个字符,输出如:10)// h 时(只需此一个字符,输出如:上/下午 1 ~ 12) // H 时(只需此一个字符,输出如:0 ~ 23) // k 一天中的第几个小时(只需此一个字符,输出如:1 ~ 24)// K 时(上/下午 0 ~ 11)// m 一小时中的第几分(只需此一个字符,输出如:30)// s 一分钟中的第几秒(只需此一个字符,输出如:55)// S 毫秒(只需此一个字符,输出如:978)// E 星期几(E/EE/EEE:Tue, EEEE:Tuesday, EEEEE:T)// c 独立星期几(c/cc/ccc:Tue, cccc:Tuesday, ccccc:T)// D 一年中的第几天(只需此一个字符,输出如:189)// F 一月中的第几个星期几(只需此一个字符,输出如:2)// w 一年中的第几个星期(只需此一个字符,输出如:27)// W 一月中的第几个星期(只需此一个字符,输出如:1)// a 上/下午标记符(只需此一个字符,输出如:AM/PM)// Z 时区(RFC822)(Z/ZZ/ZZZ:-0800 ZZZZ:GMT-08:00 ZZZZZ:-08:00)// z 时区(z/zz/zzz:PST zzzz:Pacific Standard Time)

11.指定app登陆界面
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

12.RecyclerView ViewHolder 和 Adapter 
RecyclerView 只创建刚好充满屏幕的12个视图,而不是100个视图。用户
滑动屏幕切换视图时,上一个视图会被回收利用。顾名思义, RecyclerView所做的就是回收再
利用,循环往复。 在oncreateview方法中会设置显示方式和绑定adapter和viewholder
adapter负责:
 创建必要的ViewHolder;
 绑定ViewHolder至模型层数据。 

ViewHolder只做一件事:容纳View视图

13.Android开发常用到单例的一大原因是
它们比fragment或activity活得久。例如,在设备旋转
或是在fragment和activity间跳转的场景下,单例不会受到影响,而旧的fragment或activity已经不
复存在了 
14.是否要保留fragment

首先,相比非保留fragment,保留fragment的显示非常复杂。一旦出现问题,排查起来非常
耗时。既然使用它会让程序复杂起来,能不用就不用吧。
其次, fragment在使用保存实例状态savedInstanceState的方式处理设备旋转时,也能够应对所有生命周期场景;
但保留的fragment只能处理activity因设备旋转而销毁的情况。如果activity是因操作系统需要回收
内存而被销毁,则所有保留的fragment也会随之销毁,数据也就跟着丢失了。即使没有销毁,在activity实例进程关闭时,fragment也会被销毁,因此savedInstanceState保存的时间更久一点。 
15.任务与后退栈

任务是用户比较关心的activity栈。栈底部的activity通常称为基activity。用户可以看到栈顶的
activity。用户点击后退键时,栈顶activity会弹出栈外。如果当前屏幕上显示的是基activity,点击
后退键,系统会退回主屏幕。
在当前任务中启动activity的好处是,用户可以在任务内而不是在应用层级间导航返回
当前,从NerdLauncher启动的任何activity(可能是别的应用的)都会添加到NerdLauncher任务中
16.进程与任务
尽管存在未知的异常情况,但总的来说, Android世界里的每个应用组件都仅与一个进程相
关联。应用伴随着自己的进程一起完成创建,该进程同时也是应用中所有组件的默认进程。
(虽然组件可以指派给不同的进程,但我们推荐使用默认进程。如果确实需要在不同进程中
运行应用组件,通常也可以借助多线程来达到目的。相比多进程的使用, Android多线程的使用
更加简单。)
每一个activity实例都仅存在于一个进程和一个任务中。这也是进程与任务的唯一相似之处。任
务只包含activity,这些activity通常来自于不同的应用;而进程则包含了应用的全部运行代码和对象。
进程与任务很容易让人混淆,主要原因在于它们不仅在概念上有某种重叠,而且通常都是以
其所属应用的名称被人提及的。例如,从NerdLauncher启动器中启动CriminalIntent应用时,操作
系统创建了一个CriminalIntent进程以及一个以CrimeListActivity为基activity的新任务。在
overview screen中,我们可以看到标签为CriminalIntent的任务。

打开CriminalIntent应用,选择任何crime项,然后点击CHOOSE SUSPECT按钮。这会打开联
系人应用让我们选择目标联系人。随即,联系人activity会被加入CriminalIntent应用任务。如果此
时点击后退键在不同activity间切换的话,用户可能意识不到他们正在进程间切换。
然而,联系人activity实例确实是在联系人应用进程的内存空间创建的,而且也是在该应用进
程里的虚拟机上运行的。这可以从图22-13中看出。 
为进一步了解进程和任务的概念,让CriminalIntent应用处于运行状态,并打开联系人列表界
面。(继续之前,请确保联系人应用没有在overview screen出现。)点击主屏幕键回到主屏幕,从
中启动联系人应用。然后从联系人列表选取任意联系人,或添加新的联系人。
在这个操作过程中,会在联系人应用进程中创建新的联系人列表activity和联系人明细界面实
例。联系人应用新任务也会完成创建。这个新任务会引用联系人列表activity和联系人明细界面实
例,如图22-14所示。 



在发送crime消息时,你所选择发送消息应用的activity不会添加到
CriminalIntent应用任务中,而是添加到它自己的独立任务中
在Lollipop设备上,对以android.intent.action.SEND或action.intent.action.SEND_
MULTIPLE操作启动的activity,隐式intent选择器会创建独立的新任务。(在旧设备上,Gmail的
activity是直接添加给CriminalIntent应用任务的。) 在Lollipop之前的设备上查看overview
screen的话,你只能看到孤零零的一个任务。前面已说过, Lollipop之前的系统需要在manifest中
提前定义应用任务,所以系统无法为单个应用动态创建多个任务。

17.线程如果创建了大量的AsyncTask,或者长时间运行AsyncTask,那么很可能就是错用了它。
自Android 3.2版本起,AsyncTask不再为每一个AsyncTask实例单独创建线程。相反,
它使用一个Executor在单一的后台线程上运行所有AsyncTask后台任务。这意味着每个
AsyncTask都需要排队逐个运行。显然,长时间运行的AsyncTask会阻塞其他AsyncTask。
此时可使用Handler与主线程通信

第二遍总结:

1.Framelayout是最简单的layout,他是通过各个view的layout_gravity来确定位置。
2.startactivity并不是Activity的静态方法,他是通过交给操作系统的activityManager来启动别的应用,第一个参数指定要启动的activity在哪个包的content,并且通过getIntent() 获取startactivity传过来的intent。
3.显示intent主要用于同一应用中不同组件中。
4.调用Activity.finish()方法同样可以将CheatActivity从栈里弹出 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: