The following setting avoids an activity restart incase of orientation changes or position of the physical keyboard (hidden / visible).
<activity android:name=".ProgressTestActivity" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden|keyboard">
</activity>
Android程序启动时,同时会启动一个主线程,主要负责处理UI相关事件,所以主线程通常被叫做UI线程。当多个线程并发操作UI组件时,可能导致线程安全问题。为了解决这个问题,Android制定了一条简单的规则:只允许UI线程修改Activity里的UI组件。而这个规则也会导致新的问题,即新启动的线程无法动态改变界面组件的属性,此时需要借助Handler的消息传递机制来改变UI组件,Android提供了如下几种解决方案:(1)使用Handler实现线程之间的通信(2)Activity.runOnUiThread(Runnable)(3)View.post(Runnable)(4)View.postDelayed(Runnable,long)。
配置Activity时可以指定android:launchMode属性,用于指定该Activity的加载模式:(a)standard,标准模式,默认的加载模式(b)singleTop,Task项单例模式(c)singleTask,Task内单例模式(d)singleInstance,全局单例模式。Android采用Task来管理多个Activity,启动一个应用时就会创建一个Task,可以调用getTaskId()方法来获得Activity所在Task的ID。Task以栈的形式来管理Activity,先启动的Activity被放在Task栈底,后启动的Activity被放在Task栈顶。Activity的加载模式launchMode就负责管理实例化、加载Activity的方式,并可以控制Activity与Task之间的加载关系。(1)standard:通过该模式启动Activity时,Android总会为目标Activity创建一个新的实例,并将该Activity添加到当前Task栈中。这种模式不会启动新的Task,新Activity被添加到原有的Task中。用户按下“返回”键时,系统会将Activity从栈顶逐一删除。(2)singleTop:与standard基本相似,但当被启动的Activity已经位于栈顶时,系统不会重新创建Activity的实例,而是直接复用已有的Activity实例。(3)singleTask:在同一个Task内只有一个Activity实例。如果要启动的Activity不存在,会创建新的Activity实例并加入栈顶;如果目标Activity已位于栈顶,此时与singleTop模式行为相同,直接复用;如果目标Activity存在但不在栈顶,系统会把位于目标Activity上的所有Activity移出Task栈,使目标Activity转入栈顶。(4)singleInstance:系统保证无论从哪个Task中启动目标Activity,只会创建一个目标Activity实例,并会使用一个全新的Task栈来装载该实例。如果目标Activity不存在,会创建全新的Task,再创建目标Activity实例;如果已存在,无论位于哪个应用或Task中,系统会把该Activity所在Task转到前台,使该Activity显示出来。采用该模式,Activity总位于栈顶,所在Task只包含该Activity。
在使用下拉列表Spinner时,如果你在onCreate中调用了getSelectedItemPosition方法,即使你只是设置listener,它的setOnItemSelectedListener事件也会自动执行。
AsyncTask用的是线程池机制,容量是128,最多同时运行5个core线程,剩下的排队。所以有时候,使用AsyncTask会很慢,甚至导致doInBackground不会执行。如果要停止AsyncTask的执行,不仅要调用cancel方法,还要在AsyncTask内部调用iscancelled方法来决定是否终止AsyncTask。某些情况下,即使你设置了标志位或者调用了cancel方法也不能结束AsyncTask的执行,也许是AsyncTask内部阻塞了,所以AsyncTask一直为running状态。
permission是自己定义权限,uses-permission是申请权限。调用Android函数时,要考虑到权限,如果配置文件中没有获取权限,会出现异常。比如获取DeviceID需要ReadPhoneState权限,获取Mac地址需要AccessWifiState权限。
动态加载布局时,将layout文件变为View,可以使用LayoutInflater:
LayoutInflater flater = LayoutInflater.from(this);
View view = flater.inflate(R.layout.example, null);
Button button = (Button) view.findViewById(R.id.button);