Android19-高級技巧

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

  1. RTC : 表示讓定時任務的觸發(fā)時間從1970年1月1日0時開始算起胚泌,但不會喚醒CPU
  2. ELAPSED_REALTIME_WAKEUP : 表示讓定時任務的觸發(fā)時間從系統(tǒng)開機算起省咨,但會喚醒CPU。
  3. 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為只支持豎屏僚匆。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末微渠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子咧擂,更是在濱河造成了極大的恐慌逞盆,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件松申,死亡現(xiàn)場離奇詭異云芦,居然都是意外死亡,警方通過查閱死者的電腦和手機贸桶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門舅逸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人皇筛,你說我怎么就攤上這事琉历。” “怎么了水醋?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵旗笔,是天一觀的道長。 經(jīng)常有香客問我拄踪,道長蝇恶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任宫蛆,我火速辦了婚禮艘包,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘耀盗。我一直安慰自己想虎,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布叛拷。 她就那樣靜靜地躺著舌厨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪忿薇。 梳的紋絲不亂的頭發(fā)上裙椭,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音署浩,去河邊找鬼揉燃。 笑死,一個胖子當著我的面吹牛筋栋,可吹牛的內(nèi)容都是我干的炊汤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抢腐!你這毒婦竟也來了蒸辆?” 一聲冷哼從身側(cè)響起布疼,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎强岸,沒想到半個月后魄懂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挂谍,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡厂庇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年投剥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片提完。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡形纺,死狀恐怖丘侠,靈堂內(nèi)的尸體忽然破棺而出徒欣,到底是詐尸還是另有隱情,我是刑警寧澤蜗字,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布打肝,位于F島的核電站,受9級特大地震影響挪捕,放射性物質(zhì)發(fā)生泄漏粗梭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一级零、第九天 我趴在偏房一處隱蔽的房頂上張望断医。 院中可真熱鬧,春花似錦奏纪、人聲如沸鉴嗤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽醉锅。三九已至,卻和暖如春发绢,著一層夾襖步出監(jiān)牢的瞬間硬耍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工边酒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留经柴,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓墩朦,卻偏偏與公主長得像坯认,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容