Android第一行代码——14章继续进阶-你还应该掌握的高级技巧

文章目录

  • 全局获取Context的技巧
  • 使用Intent传递对象
    • Serializable
    • Parcelable
  • 定制自己的日志工具
  • 创建定时任务
    • Alarm机制
    • Doze模式
  • 多窗口模式
    • 禁用多窗口模式
  • Lambda表达式

全局获取Context的技巧

 Android提供了一个Application类,每当应用程序启动的时候,系统就会自动把这个类进行初始化。我们可定制一个自己的Application类,用于获取全局Context
示例:
 1.创建Application的子类对象,提供获取content的方法

import android.app.Application;
import android.content.Context;

public class MyApplication extends Application {
     
    private static Context context;

    @Override
    public void onCreate() {
     
        super.onCreate();
        context = getApplicationContext();
    }
    //提供getContext()方法
    public static Context getContext(){
     
        return context;
    }
}

 2.在AndroidManifest.xml文件的application标签下指定,告知系统启动的是MyApplication,而不是默认的Application

<application
        android:name=".MyApplication"
   ......
    </application>

问题:为了让LitePal正常工作,必须要配置

<application
        android:name="org.litepal.LitePalApplication"
   ......
    </application>

 这样配置之后,LitePal就可在内部自动获取到Context了。但是这样既无法配置MyApplication了,因为一个项目只能配置一个Application
解决办法:在我们自己的Application中调用LitePal的初始化方法就行

public class MyApplication extends Application {
     
    private static Context context;

    @Override
    public void onCreate() {
     
        super.onCreate();
        context = getApplicationContext();
        LitePal.initialize(context);
    }
    //提供getContext()方法
    public static Context getContext(){
     
        return context;
    }
}

使用Intent传递对象

平时我们在用Intent传递数据时都用的putExtra()方法,但是当我们要传递的数据是自定义对象时,无法传递。实现方法如下:

Serializable

序列化的意思,表示吧一个对象转换成可储存或可传输的状态,序列化后的对象可以在网络上传输,也可储存到本地
是一个接口,用时直接实现接口就可

  class Person implements Serializable{
     
        private String name;
        private int age;

       public String getName() {
     
               return name;
       }

      public void setName(String name) {
     
             this.name = name;
       }
      public int getAge() {
     
             return age;
       }
      public void setAge(int age) {
     
           	this.age = age;
       }
 }

发送:

 Person person = new Person();
            person.setAge(12);
            person.setName("dag");
            Intent intent = new Intent(MainActivity.this,MainActivity2.class);
            intent.putExtra("person_data",person);
            startActivity(intent);

接收:(注意:与原来的接收不同)

 Intent intent = getIntent();
 Person person = (Person)intent.getSerializableExtra("person_data");

Parcelable

它的实现原理是将一个完整的对象进行分解,分解后的每一部分都是Intent所支持的数据类型

class people implements Parcelable{
     

    private String name;
    private int age;

    public String getName() {
     
        return name;
    }

    public void setName(String name) {
     
        this.name = name;
    }

    public int getAge() {
     
        return age;
    }

    public void setAge(int age) {
     
        this.age = age;
    }

	//直接返回0
    @Override
    public int describeContents() {
     
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
     
        //调用Parcel的writeXXX方法,吧类中的字段一一写出
        dest.writeString(name);
        dest.writeInt(age);
    }
    public static final Parcelable.Creator<people> CREATOR = new Parcelable.Creator<people>(){
     

        @Override
        public people createFromParcel(Parcel source) {
     
            //读取刚才写出的name和age字段,读取顺序一定要和写入的完全相同
            people people1 = new people();

            people1.name = source.readString();
            people1.age = source.readInt();
            return people1;
        }
		
        @Override
        public people[] newArray(int size) {
     
            return new people[size];
        }
    };
}

发送:

people people1 = new people();
        people1.setAge(12);
        people1.setName("134455");
        Intent intent1 = new Intent(MainActivity.this,MainActivity2.class);
        intent.putExtra("people_data",person);
        startActivity(intent);

接收:(注意:与原来的接收不同)

Intent intent = getIntent();
people people1 = (people) intent.getParcelableExtra("people_data");

定制自己的日志工具

目的:自由的控制日志的打印
示例:

class LogUtil{
     
    public static final int VERBOSE = 1;
    public static final int DEBUG = 2;
    public static final int INFO = 3;
    public static final int ERROR = 5;
    public static final int WARN = 4;
    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);
    }

}

之后只需要修改level变量,就可控制打印情况

创建定时任务

 Android中的定时任务一般有两种实现方式,一种是Java API里的Timer类,一种是Android的Alarm机制
  Timer并不太实用于那些需要长期在后台运行的定时任务,当长时间时,CPU进入到睡眠状态,可能导致Timer的定时任务无法正常运行

Alarm机制

  可以保证大多数情况下需要执行定时任务时CPU都能正常工作
如下是一个长时间在后台定时运行的服务

public class LongRuningService extends Service {
     
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
     
        return null;
    }
    /*
    一旦启动LongRuningService就会在onStartCommand中执行一个定时任务,
    	这样一个小时后将在此启动LongRuningService,形成循环
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
     
        new Thread(new Runnable() {
     
            @Override
            public void run() {
     
                //执行具体的操作逻辑
            }
        }).start();
        //获取AlarmManager对象
        AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
        int anHour = 60*60*1000;
        Long l = System.currentTimeMillis();
      	//SystemClock.elapsedRealtime()获取开机至今的毫秒数
       //System.currentTimeMillis() 获取1970年 一月一日0点至今所经历的毫秒数
        Long triggerAtTime = SystemClock.elapsedRealtime()+anHour;
        Intent intent1 = new Intent(this,LongRuningService.class);
        PendingIntent pendingIntent = PendingIntent.getService(this,0,intent1,0);
        //设置定时任务
        manager.set(AlarmManager.RTC_WAKEUP,triggerAtTime,pendingIntent);
        /*三个参数:
         第一个是整型参数用于指定AlarmManager的工作类型
           第二个:触发时间
           第三个是 PendingIntent

         */
        return super.onStartCommand(intent,flags,startId);
    }
}

AlarmManager的工作类型 说明
ELAPSED_REALTIME 让定时任务从系统开机开始算起,但不会唤醒CPU
ELAPSED_REALTIME_WAKEUP 让定时任务从系统开机开始算起,唤醒CPU
RTC 让系统任务从1970年一月一日0点开始算起,但不会唤醒CPU
RTC_WAKEUP 让系统任务从1970年一月一日0点开始算起,唤醒CPU

注:对于不同的工作类型,要选择不同的时间
如果你要求Alarm任务的执行时间必须准确无误,应用setExact()方法替换set()方法

Doze模式

 当用户设备是Android 6.0 或以上系统时,如果未插接电源,且屏幕关闭了一段时间之后就会进入到Doze模式
  在该模式下,系统会对CPU,网络,Alarm等活动进行限制,从而延长电池的使用寿命
 当然,它不会一直处于该模式,而是会间隙性的退出Doze模式一小段时间,在这段时间中去完成同步操作,Alarm任务
注:Doze模式下,Alarm任务就会变的不准时,解决方案
 吧set()方法换成setExactAndAllowWhileIdle()或setAndAllowWhileIdle()方法就可让定时任务在Doze模式下也可正常执行

多窗口模式

即我们常见的分屏操作,在该模式下活动会有一个重新创建的过程,如果操作一个程序,另一个程序会进入暂停状态(onPause)

 如果你想改变进入多窗口模式活动被重新创建,可添加如下配置

<activity android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|screenSize|screenLayout">
           .....
        </activity>

禁用多窗口模式

<application
		....
        android:resizeableActivity="false">
      .....  
</application>      

true表示支持,false表示不支持,默认是支持

Lambda表达式

android studio 中的配置

1.app的build文件下配置好

jackOptions{
     
            enabled true
        }
compileOptions{
     
   sourceCompatibility JavaVersion.VERSION_1_8
   targetCompatibility JavaVersion.VERSION_1_8
 }

  retrolambda {
     //指定将源码编译的级别,使用下列代码,会将代码编译到兼容1.6的字节码格式
        javaVersion JavaVersion.VERSION_1_6
    }

2.项目build文件下也要加上配置

apply plugin: 'me.tatarka.retrolambda'//lambda
dependencies {
     
        classpath 'com.android.tools.build:gradle:3.1.3'
        classpath 'me.tatarka:gradle-retrolambda:3.7.0' //lambda

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

剩下的使用和java使用方法一样
Lambda表达式

你可能感兴趣的:(#,Android第一行代码,java,android,android,studio,spring,linux)