一、全局获取Context
一般我们获取context都是在activity中,直接用this就好,但是好多情况写不是在activity中也需要用到context,这时只要定义一个全局context,在程序初始化的类中获取
public class MyApplication extends Application { private static Context context; @Override public void onCreate() { super.onCreate(); context = getApplicationContext(); } public static Context getContext(){ return context; } }这样就可以用在工程的任何地方直接使用上下文context了
二、使用intent传递对象
平时最常用的Intent传递基本数据,,但是intent.putExtra()支持的数据类型是有限的,如果我们传递一个自定义对象的时候怎么办呢??
2.1 使用serializable
定义:serializable是序列化的意思,表示一个对象转化成可存储或者可传输的状态,即序列化后的对象可以在网络上传输,也可以保存到版本地。方法:对象类实现serializable类具体实现 //第一步:定义对象类并实现serializable public class Person implements Serializable { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } } //第二步:通过putExtra传值 private void putObject() { Person person = new Person(); person.setAge("20"); person.setName("tom"); Intent intent = new Intent(MyApplication.getContext(), MyService.class); intent.putExtra("person", person); startActivity(intent); } //获取传过来的对象 private void getObject() { Person person = (Person) getIntent().getSerializableExtra("person"); }2.1使用Parcelable
原理:Parcelable可以实现和serializable同样的效果,大并不是将对象序列化,而是讲一个完整的对象进行分解,分解后的每一部分都是Intent支持的数据类型,这样就可以实现传递对象的功能。具体实现 //第一步:创建对象类类并实现parcelable public class Person implements Parcelable { private String name; private String age; @Override public int describeContents() { return 0; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(name);//写出name parcel.writeString(age);//写出age } public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() { @Override public Person createFromParcel(Parcel parcel) { Person person = new Person(); person.name = parcel.readString();//读取name person.age = parcel.readString();//读取age return person; } @Override public Person[] newArray(int size) { return new Person[size]; } }; } //第二步:传递对象 private void putObject() { Person person = new Person(); person.setAge("20"); person.setName("tom"); Intent intent = new Intent(MyApplication.getContext(), MyService.class); intent.putExtra("person", person); startActivity(intent); } //第三步:获取对象 private void getObject() { Person person = (Person) getIntent().getParcelableExtra("person"); } parcelable解析 parcelable的实现方式稍微复杂一点,首先让parcelable实现对象类,重写方法describeContents()方法直接返回0就好了,writeToParcel()方法中调用Parcel的writeXXX()方法,将person的字段一一写出。 另外,必须在person类中提供一个名为CREATOR的常量,这里创建了Parcelable.create接口的一个实现,并将泛型指定为Person,接着冲写方法createFromParcel和newArray()两个方法,在第一个方法中读取刚才写出的name和age字段,并创建一个person对象返回。三、定制自己的日志工具
目的:测试阶段显示日志,正式上线关闭日志好处:提高程序运行效率,避免机密性数据暴露出去做一个日志工具就能实现该功能 package com.yunjiai.admin.anfly; import android.util.Log; /** * Created by Anfly on 2018/2/17. */ 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 final 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); } } } 使用说明 //只要我们修改level的值就可以自由的控制日志打印行为 //当level=nothing的时候什么都不打印出来四、创建定义任务
说明 :Android中定时任务一般是Timer和Alarm,Timer有一个缺点就是CPU进入休眠状态后不能工作,而timer具有唤醒CPU的功能。一般手机都会有自己的休眠策略,对于长期需要定时的工作Timer就不行了,需要AlarmAlarm //1、获取AlarmManager实例 //十秒是后执行任务 int time = 10 * 1000; long triggerAtTime = SystemClock.elapsedRealtime() + time; Intent intent = new Intent(this,LongRunningService.class); PendingIntent pi = PendingIntent.getService(this, 0, intent, 0); //AlarmManager的set()方法就可以设置一个定时任务 //第一个参数:用于指定AlarmManager的工作类型, alarmManager.set(AlarmManager.ELAPSED_REALTIME,triggerAtTime,pi); 详细解析:http://blog.csdn.net/wdyshowtime/article/details/73496876五、Doze模式
什么是Doze模式: 当用户系统是6.0或者以上系统时,如果设备未插电源,处于静止状态(7.0删除这一条件),屏幕关闭一段时间之后就会进入doze模式。Doze模式下,系统会对CPU、网络、alarm等活动进行限制,从而延迟电池使用寿命。当然,系统并不会一直处于Doze模式,而是间歇性的退出Doze一小段时间,这段时间中应用完成他们的同步操作、Alarm任务等。随着设备进入Doze时间越长,间歇性的退出Doze模式的时间间隔也会越长 Doze模式下哪些功能收到限制 网络访问被禁止系统忽略唤醒CPU或者屏幕的操作系统不再执行WiFi扫描系统不再执行的同步服务Alarm任务将会在下次Doze模式的时候执行六、多窗口模式
随着手机屏幕的增大,同一个屏幕同时打开多个应用的需求越来越迫切,于是Android7.0中引入一个特色功能—多窗口模式。
首先认识手机按键:home 和 back经常用,OverView用的比较少打开多窗口的两种方式
在OverView列表界面长按任意一个应用拖动即可打开任意一个应用,长按overview即可进入多窗口模式下的生命周期
多窗口模式并不会改变原有activity的生命周期,只会将用户最近的交互过的那个activity设置为运行状态,而将多窗口模式下的另一个课件的activity设置为暂停状态。如果此时用户又去和暂停的activity交互,该activity变成运行状态,之前处于运行状态的activity变为暂停状态。 这个过程仅仅是onPause()和onResume()切换 注意:切换为多窗口的时候对应的activity经历重新创建,为了避免这个默认行为,在AndroidManifest中设置android:configChanges="orientation|keyboardHidden|screeSize|screenLayout"
禁用多窗口模式——AndroidManifest中设置
<application ... android:resizeableActivity="false" ...> </application>此时无法进入多窗口模式,但是有一个问题,targetSdkVersion>=24才有效,如果想要使用必须是设置为竖屏才有效,android:screenOrientation="portrait"
七、Lambda表达式
lambda是Java8支持的特色功能,他对Android最低版本兼容是Android2.3lambda本质上是一种匿名方法,他既没有方法名,也没有访问修饰符和返回值类型,使用它编写代码会更加简洁,也更加易读。使用Java8新特性配置 defaultConfig { ... jackOptions.enabled = true } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } 重点:凡是只有一个待实现方法接口,都可以使用lambda表达式的写法使用①:创建线程
//lambda写法 new Thread(() -> { //逻辑 }).start(); //传统写法 new Thread(new Runnable() { @Override public void run() { //逻辑 } }).start();使用②:点击事件
//传统写法 btn_map.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //逻辑 } }); //lambda写法 btn_map.setOnClickListener(view ->{ //逻辑 Toast.makeText(MainActivity.this, "lambda写法 ", Toast.LENGTH_SHORT).show(); });