文章目錄
- 1.全域獲得Context的技巧
- 2.使用Intent傳遞物件
- 2.1Serializable方式
- 2.2Parcelable方式
- 3.定制自己的日志工具
- 4.創建定時任務
- 4.1Alarm機制
- 4.2Doze模式
- 5.多視窗模式編程
- 5.1多視窗模式下的生命周期
- 5.2禁用多視窗模式
1.全域獲得Context的技巧
在我們學習Android基礎知識的時候,你會發現在很多地方我們都會使用到Context,彈出Toast的時候需要,啟動活動的時候需要,發送廣播的時候需要,操作資料庫的時候需要,使用通知的時候需要,等等等等,所以有時候在需要使用Context時,卻不知道該怎么獲得Context將會是一件非常傷腦筋的事情,本節我們就來介紹一個全域獲得Context的技巧,
使用步驟:
1.新建類繼承Application類,在其中獲取Context并定義一個用于外部獲取Context的方法,
2.給AndroidManifest.xml設定android:name屬性,也就是告知系統,當程式啟動時應該初始化MyApplication類,而不是默認的Application類,
示例:
//步驟一
public class MyApplication extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context=getApplicationContext();
}
public static Context getContext(){
return context;
}
}
//步驟二
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.temp">
<application
android:name=".MyApplication"//告知系統當程式啟動時初始化MyApplication類
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
這里還有個小問題:在我們學習LitePal時我們也需要設定AndroidManifest.xml中的android:name屬性,那當你兩者都想要使用時該怎樣處理呢?其實解決方法也很簡單,我們只需在我們自己的Application中呼叫LitePal的初始化方法即可,
示例:
public class MyApplication extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context=getApplicationContext();
LitePal.initialize(context);
}
public static Context getContext(){
return context;
}
}
2.使用Intent傳遞物件
Intent傳遞基礎型別的資料相信你已經比較熟悉了,可是如果我們想要用Intent傳遞一個物件的話那該怎樣處理呢?本節我們就來學習一下使用Intent傳遞物件,
2.1Serializable方式
使用步驟:
1.定義一個你想要傳遞的類,并讓該類繼承Serializable介面,
2.呼叫putExtra()方法向Intent中存盤物件,呼叫getSerializableExtra()方法從Intent中獲取物件,
Serializable詳解:Serializable是序列化的意思,表示將一個物件轉換成可存盤或可傳輸的狀態,序列化后的物件可以在網路上進行傳輸,也可以存盤到本地,
示例:
//步驟一
public class Student implements Serializable {
String name;
int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
}
//步驟二
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button=(Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,MainActivity2.class);
Student student=new Student("Tom",18);
intent.putExtra("Student",student);//向Intent中存盤物件
startActivity(intent);
}
});
}
}
public class MainActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Intent intent=getIntent();
Student student= (Student) intent.getSerializableExtra("Student");//從Intent中獲取物件
Toast.makeText(MainActivity2.this,student.name,Toast.LENGTH_SHORT).show();
}
}
2.2Parcelable方式
使用步驟:
1.定義一個你想要傳遞的類,讓其繼承Parcelable介面并實作介面中的一些方法,
2.呼叫putExtra()方法向Intent中存盤物件,呼叫getParcelableExtra()方法從Intent中獲取物件,
Parcelable詳解:Parcelable方式的實作原理是將一個完整的物件進行分解,而分解后的每一部分都是Intent所支持的資料型別,這樣也就實作傳遞物件的功能了,
示例:
//步驟一
public class Student implements Parcelable {
String name;
int age;
public Student(){
}
public Student(String name,int age){
this.name=name;
this.age=age;
}
public static final Creator<Student> CREATOR = new Creator<Student>() {
@Override
public Student createFromParcel(Parcel in) {
Student student=new Student();
student.name=in.readString();//讀取name(注意這里的讀取順序要和寫入順序完全相同)
student.age=in.readInt();//讀取int
return student;
}
@Override
public Student[] newArray(int size) {
return new Student[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);//寫出name
parcel.writeInt(age);//寫出age
}
}
//步驟二
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button=(Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,MainActivity2.class);
Student student=new Student("Tom",18);
intent.putExtra("Student",student);//向Intent中存盤物件
startActivity(intent);
}
});
}
}
public class MainActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Intent intent=getIntent();
Student student= (Student) intent.getParcelableExtra("Student");//從Intent中獲取物件
Toast.makeText(MainActivity2.this,student.name,Toast.LENGTH_SHORT).show();
}
}
3.定制自己的日志工具
現在讓我們設想一個場景,你正在撰寫一個比較龐大的專案,期間為了方便除錯,在代碼的很多地方都列印了大量的日志,最近專案已經基本完成了,但是卻有一個非常令人頭痛的問題,之前用于除錯的那些日志,在專案正式上線之后仍然會照常列印,這樣不僅會降低程式的運行效率,還有可能將一些機密性的資料泄露出去,那可能會有人說我把列印日志的代碼一行一行全部刪掉就行了,這顯然不是什么好點子,不僅費事費力,而且以后你繼續維護這個專案時可能還會需要這些日志,本節我們就來學習該如何優雅的解決這個問題,
解決方法:
事實上這個問題的解決方法非常簡單,我們只需要定義一個自己的日志工具,并在里面對列印日志條件加上限制條件即可,
示例:
public class LogUtil {
private static final int VERBOSE=1;
private static final int DEBUG=2;
private static final int INFO=3;
private static final int WARN=4;
private static final int ERROR=5;
private static final int NOTHING=6;
private static int level=VERBOSE;//我們只需要更改level的值即可對不同等級的列印陳述句進行限制,而當我們不想列印任何日志時,我們只需將level的值設定為NOTHING即可,
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);
}
}
}
4.創建定時任務
Android中的定時任務一般有兩種實作方式,一種是java API里提供的Timer類,一種是使用Android的Alarm機制,而兩者的區別在于:Android手機會在長時間不操作的情況下自動讓CPU進入到睡眠狀態,這就有可能導致Timer中的定時任務無法正常運行,而Alarm則具有喚醒CPU的功能,(這里要注意喚醒CPU和喚醒螢屏完全是兩個概念)
4.1Alarm機制
使用步驟:
1.獲取AlarmManager實體,
2.呼叫manager.set()方法創建定時任務,
示例:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button=(Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,MainActivity2.class);
PendingIntent pendingIntent=PendingIntent.getActivity(MainActivity.this,0,intent,0);
AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);//步驟一
long time= SystemClock.elapsedRealtime()+1000;
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,time,pendingIntent);//步驟二
}
});
}
}
manager.set()方法詳解:第一個引數同于設定作業型別,ELAPSED_REALTIME型:表示定時任務的觸發時間從系統開機開始算起,但不會喚醒CPU;ELAPSED_REALTIME_WAKEUP型別:表示定時任務的觸發時間從系統開機開始算起,且會喚醒CPU;RTC型別:表示定時任務的觸發時間從1970年1月1日0點開始算起,但不會喚醒CPU;RTC_WAKEUP型別:表示定時任務的觸發時間從1970年1月1日0點開始算起,且會喚醒CPU,第二個引數就是定時任務的觸發時間,以毫秒為單位(注意要與第一個引數相匹配),第三個引數就是定時調度任務要執行的具體事件了,
注意:從Android4.4系統開始,Alarm任務的觸發事件會變得不準確,有可能會延遲一段時間后才會執行,當然這可不是Bug,這只是為了能讓手機更好的節省電量,但倘若你要求Alarm任務的執行時間必須準確無誤,那么你只需將set()方法更改為setExact()方法即可,
4.2Doze模式
Doze模式是Android6.0系統新加入的一種省電模式,該模式下系統會對CPU,網路,Alarm等活動進行限制,從而延長電池的使用壽命,因此這種模式也就極大的影響了我們Alarm任務的執行時間,不過倘若你真的有非常特殊的需求,要求在Doze模式下Alarm任務也要必須正常執行,Android還是提供了解決方案的,我們只需呼叫AlarmManger的setAndAllowWhileIdle()或setExactAndAllowWhileIdle()方法即可讓你的Alarm任務在Doze模式下也能正常執行了,
5.多視窗模式編程
多視窗模式也就是我們現在經常說的分屏模式了,
5.1多視窗模式下的生命周期
當一個活動進入多視窗模式或橫豎屏切換時,該活動會重新創建,多視窗模式下正在與用戶互動的活動處于onResume狀態,另一個則處于onPause狀態,
另外,針對于進入多視窗模式時活動就會被重現創建,如果你想改變這一默認行為,只需在AndoridManifest.xml檔案中進行如下配置即可:
<activity android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize|screenLayout">
加入了這行配置之后,不管是進入多視窗模式,還是橫豎屏切換,活動都不會被重新創建,而是會將螢屏發生改變的事件通知到Activity的onConfigurationChanged()方法當中,
5.2禁用多視窗模式
禁用多視窗模式的方法非常簡單,只需在AndroidManifest.xml的< application >或< activity >標簽下加入如下屬性即可:
android:resizeableActivity=["true"|"false"]
其中,true表示應用支持多視窗模式,false表示應用不支持多視窗模式,該屬性默認為true,
不過上面的方法只能在targetSdkVersion為24以上時才會有用,否則這個屬性是無效的,不過Android規定,當targetSdkVersion為24以下,并且活動不允許橫豎屏切換,那么該應用也將不支持多視窗模式,配置方法如下:
android:screenOrientation=["portrait"|"landscap"]
其中,portrait表示活動只支持豎屏,landscap表示活動只支持橫屏,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/99484.html
標籤:其他
上一篇:它讓你的世界更精彩
