1.全局獲取Context
Android提供了一個Application類腐晾,每當應用啟動的,系統(tǒng)就會自動將這個類進行初始化川尖,而我們可以定制一個自己的Application類登下,以便于管理程序內(nèi)一些全局的狀態(tài)信息,比如全局的Context叮喳。
1.自定義Application類
>public class MyApplication extends Application {
private static Context context;
@Override
public void onCreate() {
//重寫onCreate()方法被芳,獲得context對象
context = getApplicationContext();
}
public static Context getContext() {
//外界調(diào)用,獲得context
return context;
}
}
2.在AndroidManifest.xml文件中指定加載MyApplication
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
3.外界調(diào)用的時候
Toast.makeText(MyApplication.getContext(), "點擊了頭像", Toast.LENGTH_SHORT).show();
2.使用Intent傳遞對象
Intent使用putExtra()方法傳遞數(shù)據(jù)時馍悟,所支持的類型是有限的畔濒,當需要傳遞一些自定義對象時,就需要使用Serializable或者Parcelablc的方式來實現(xiàn)了锣咒。
一侵状、Serializable方式
Serializable是序列化的意思赞弥,表示將一個對象轉(zhuǎn)換成可存儲或可傳輸?shù)臓顟B(tài),序列化后的對象可以在網(wǎng)絡上進行傳輸趣兄,也可以存儲到本地绽左,至于序列化的方法也很簡單,只需要讓一個類去實現(xiàn)Serializable這個接口就可以了艇潭。
1.1比如一個Person類拼窥,其中包含了name和age兩個字段,想要將它序列化就可以這樣寫:
//整個類中跟定義一個實體類大致相同蹋凝,最最重要的是在第一行鲁纠,讓Person類去實現(xiàn)Serializable接口。
public class Person implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
1.2然后需要傳遞對象的activity中:
Intent intent = new Intent(mContext, FruitActivity.class);
Person person = new Person();
person.setAge(20);
person.setName("Tom");
intent.putExtra("person_data", person); MyApplication.getContext().startActivity(intent);
1.3在需要獲取對象的acidity中:
Person person = (Person) getIntent().getSerializableExtra("person_data");
二鳍寂、Parcelabele方式
使用Parcelable同樣可以達到跟Serializable相同的效果房交,不同的是,Parcelabel方式的實現(xiàn)原理是將一個完整的對象進行分解伐割,而分解后的每一部分都是Intent所支持的數(shù)據(jù)類型候味。這樣也就實現(xiàn)傳遞對象的功能了。
2.1和Serializable一樣隔心,需要使Person實現(xiàn)Parcelable接口白群。然后重寫describeContents()和writeToParcel()這兩個方法。其中describeContents()方法中直接返回0就可以了硬霍。而writeToParcel()需要調(diào)用writeXxx()方法帜慢,將Person類中的字段一一寫出。然后還要提供一個名為CREATOR的常量唯卖。
public class Person implements Parcelable {
private String name;
private int age;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
//重寫describeContents()方法
@Override
public int describeContents() {
return 0;
}
//重寫writeToParcel()方法
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);//寫出name
dest.writeInt(age);//寫出age
}
//定義CREATOR常量
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
Person person = new Person();
person.setName(source.readString());//讀取name
person.setAge(source.readInt());//讀取age
return person;
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
2.2在需要傳遞對象的activity中,這跟Serializable是一樣
Intent intent = new Intent(mContext, FruitActivity.class);
Person person = new Person();
person.setAge(20);
person.setName("Tom");
intent.putExtra("person_data", person); MyApplication.getContext().startActivity(intent);
2.3在需要獲取對象的activity中
Person person = (Person) getIntent().getParcelableExtra("person_data");
3.定制自己的日志工具
定制日志工具粱玲,可以讓程序處于開發(fā)階段的時候就打印日志,處于上線階段的時候就不打印日志拜轨,便于后期維護抽减,也防止了私密信息的泄漏。
1.1如下橄碾,創(chuàng)建LogUtil類
public class LogUtil {
public static final int VERBOSE = 1;
public static final int DEBUG = 2;
public static final int INFO = 3;
public static final int WARN = 4;
public static final int ERROR = 5;
public static final int NOTHING = 6;
public static int level = VERBOSE;
public static void v(String tag, String msg) {
if (level <= VERBOSE) {
Log.v(tag, msg);
}
}
public static void d(String tag, String msg) {
if (level <= DEBUG) {
Log.d(tag, msg);
}
}
public static void i(String tag, String msg) {
if (level <= INFO) {
Log.i(tag, msg);
}
}
public static void w(String tag, String msg) {
if (level <= WARN) {
Log.w(tag, msg);
}
}
public static void e(String tag, String msg) {
if (level <= ERROR) {
Log.e(tag, msg);
}
}
}
1.2外界調(diào)用的時候直接通過LogUtil打印信息即可卵沉。并且當我們設置LogUtil中的level等于VERBOSE就可以把所有日志都打印出來,等于WARN就可以只打印WARN以上級的日志法牲,在發(fā)布之后史汗,將level設置成NOTHING就可以把所有日志都屏蔽掉了。
LogUtil.d("TAG", "Debug log");
4. 創(chuàng)建定時任務
Android中的定時任務一般有兩種實現(xiàn)方式拒垃,一種是使用JavaAPI提供的Timer類停撞,一種是Android的Alarm機制。兩種方式都能實現(xiàn)相同的效果悼瓮,但是Timer有可能在手機休眠的狀態(tài)下無法正常運行戈毒,而Alarm則具有喚醒CPU的功能艰猬,因此在手機休眠的狀態(tài)下也能保證定時任務的正常執(zhí)行。
一副硅、Alarm機制
Alarm機制的用法姥宝,主要是借助AlarmManager類來實現(xiàn)翅萤,這個類和NotificationManager有點類似恐疲,都是通過調(diào)用Context的getSystemService()方法傳入?yún)?shù)Context.ALARM_SERVICE來獲取實例。
1.1獲取AlarmManager實例
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
1.2調(diào)用AlarmManager的set()方法就可以設置一個定時任務了套么。比如設定一個任務在10秒后執(zhí)行
set()方法接收3個參數(shù):
第一個:一個整型參數(shù)培己,用于指定AlarmManager的工作類型,有4種值可選:>>1. RTC_WAKEUP : 表示讓定時任務的觸發(fā)時間從1970年1月1日0時開始算起,但會喚醒CPU
- RTC : 表示讓定時任務的觸發(fā)時間從1970年1月1日0時開始算起胚泌,但不會喚醒CPU
- ELAPSED_REALTIME_WAKEUP : 表示讓定時任務的觸發(fā)時間從系統(tǒng)開機算起省咨,但會喚醒CPU。
- ELAPSED_REALTIME : 表示讓定時任務的處罰時間從系統(tǒng)開機算起玷室,但不會喚醒CPU>
第二個參數(shù):定時任務出發(fā)的時間零蓉,加上第一個參數(shù)設定值。
第三個參數(shù):PendingIntent對象穷缤。這里一般會調(diào)用getService()方法或者getBroadcast()方法來獲取一個能夠執(zhí)行服務或廣播接收器的onReceive()方法就可以得到執(zhí)行敌蜂。
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
long triggerArTime = SystemClock.elapsedRealtime() + 10*1000;
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerArTime, pendingIntent);
1.3 如果需要實現(xiàn)一個長時間在后臺定時運行的服務,如下代碼津肛,每個一小時就會啟用一次服務章喉。
public class LongRunningService extends Service {
public LongRunningService() {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
//這里執(zhí)行具體的操作邏輯
}
});
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
int anHour = 60 * 60 * 1000; //一小時的毫秒數(shù)
long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
Intent i = new Intent(this, LongRunningService.class);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
return super.onStartCommand(intent, flags, startId);
}
}
1.4 最后只需要在需要啟動服務的時候調(diào)用
Intent intent = new Intent(context, LongRunningService.class);
context.startService(intent);
注:從Android4.4開始,因為系統(tǒng)在好點性方面的調(diào)整身坐,Alarm使用set()觸發(fā)任務的時間會變得不準確秸脱,如果需要讓執(zhí)行時間變得準確無誤,需使用setExact()方法來代替set()方法部蛇。
5.多窗口模式的一些設置
1.當應用進入多窗口模式的時候摊唇,活動默認會被重新創(chuàng)建,修改這一行為涯鲁,可以在AndroidManifest.xml中對活動進行如下設置
<activity
android:name=".FruitActivity"
android:theme="@style/FruitActivityTheme"
android:configChanges="orientation|keyboardHidden|screenSize|screenLayout">
</activity>
2.禁用多窗口模式
設置程序禁用多窗口模式遏片,只需在application中把android:resizeableActivity設置為false即可。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.anwser_mac.materialtest">
<application
android:resizeableActivity="false"
注:android:resizeableActivity撮竿,是在targetSdkVersion大于24才有用的吮便,如果對于一些沒有指定到24的項目,想要禁用多窗口模式幢踏,需要設置活動不允許橫豎屏切換髓需,因為Android規(guī)定targetSdkVersion小于24并且活動不允許橫豎屏切換的應用也不將不支持多窗口模式。
<activity
android:screenOrientation="portrait"http://landscape只支持橫屏房蝉,portrait為只支持豎屏僚匆。