Android第一行代码 Day11笔记

11. Android 进阶技巧

11.1 全局获取context

Application类,当程序启动,系统会自动将这个类进行初始化

流程:

  • 自定义一个类继承自Application,并重写onCreate()方法,调用getApplicationContext()方法获取一个应用程序级别的context
  • 创建一个静态方法将获取到的context返回
  • 在Manifest文件中 application标签下配置
    告知系统在程序启动时应该初始化 MyApplication类而不是默认的 Application类
android:name="com.example.intentadvancedtest.MyApplication"
  • 在使用LitePal时也会配置application
    这样会和MyApplication配置发生冲突,任何一个项目都只能配置一个Application
	android:name="org.litepal.LitePalApplication"
  • 在使用LitePal时,需要在MyApplication类中调用LitePal的初始化方法
LitePal.initialize(context);

代码示例:

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;
    }
}

11.2 使用Intent传递对象

11.2.1 使用Serializable方式传递对象

流程:

  1. 创建模型类继承自Serializable
  2. 使用Intent传参:实例化对象并赋值, 使用intent.putExtra(“key”,对象名)传参
  3. 在目标活动中获取:使用getIntent().getSerializableExtra(“key”)获取,需要强转类型

代码示例:

//TODO: 步骤1,步骤2,传参

//在目标活动中,需要强转类型
getIntent().getSerializableExtra("key");

11.2.2 使用Parcelable方式传递对象:

  1. 创建模型类实现Parcelable接口,并实现方法,在writeToParcel()中使用 parcel.write()系列方法将数据写出
  2. 提供一个CREATOR的常量,在createFromParcel()方法中,实例化对象,使用in.read()系列方法读取数据并赋值给对象,最后将对象返回
  3. 使用Intent传参:实例化对象并赋值, 使用intent.putExtra(“key”,对象名)传参
  4. 在目标活动中获取:getIntent().getParcelableExtra(“key”)获取,需要强转类型

代码示例:

//创建模型类并实现Parcelable接口
public class Student implements Parcelable {

    private String name;
    private int age;
	
	//TODO: get和set方法

    public static final Creator<Student> CREATOR = new Creator<Student>() {
        @Override
        public Student createFromParcel(Parcel in) {

            Student student = new Student();
            //读取
            student.name = in.readString();
            student.age = in.readInt();
            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) {
        //写出 name 和 age
        parcel.writeString(name);
        parcel.writeInt(age);
    }
}

//

11.3 定制日志工具

基本固定写法:

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;
    //将level指定为VERBOSE就可以把所有日志都打印出来,指定为NOTHING后,将什么都不打印
    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);
        }
    }


}

//TODO: 传参

//在目标活动中,需要强转类型
getIntent().getParcelableExtra("key");

11.4 创建定时任务

使用定时任务 Alarm机制,流程:

  1. 在服务中的onStartCommand()方法中
    开启子线程去执行具体逻辑
    使用getSystemService(ALARM_SERVICE)方法获取AlarmManager对象

  2. 使用manager.set()方法设置定时任务

    • set()方法的3个参数:
    • type:整形参数,用于指定AlarmManager的工作类型
      • ELAPSED_REALTIME: 定时任务的触发时间从系统开机开始算起,但不会唤醒CPU
      • ELAPSED_REALTIME_WAKEUP: 定时任务的触发时间从系统开机开始算起,但会唤醒CPU
      • RTC:定时任务的触发时间从1970年1月1日0点开始算起,但不会唤醒CPU
      • RTC_WAKEUP:定时任务的触发时间从1970年1月1日0点开始算起,但会唤醒CPU
    • long:定时任务触发的时间
    • pendingIntent:调用Service()或者getBroadcast()方法获取一个能够执行服务或广播的PendingIntent,当定时任务被触发时,服务的onStartCommand()方法或广播接收器的onReceive()方法就会执行
      第一个参数type如果为前两个则使用 SystemClock.elapsedRealtime():获取到系统开机至今所经历时间的毫秒数
      第一个参数type如果为后两个则使用 SystemClock.currentTimeMillis():获取1970年1月1日0点至今所经历时间的毫秒数
  3. Alarm任务的触发时间不太准确,如果要求Alarm任务的执行时间必须准确无误,则使用setExact()方法
    在Doze模式下要求Alarm任务能够正常执行调用以下两个方法,区别与set()、setExact()方法的区别一致

    • setAndAllowWhileIdle()
    • setExactAndAllowWhileIdle()

代码示例:

public class LongRunningService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public LongRunningService() {
    }

    @Override
    public void onCreate() {
        Log.d("LongRunningService","onCreate");
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Log.d("LongRunningService","onDestroy");
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtil.d("LongRunningService","onStartCommand");
        //Log.d("LongRunningService","onStartCommand");
        new Thread(new Runnable() {

            @Override
            public void run() {
            	//开启子线程执行具体逻辑
               // Log.d("LongRunningService","task");
                LogUtil.d("LongRunningService","task");
            }
        }).start();


        AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);
        int anHour = 1000;
        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);
        LogUtil.d("LongRunningService","task end");
        return super.onStartCommand(intent, flags, startId);
    }

}

11.5 多窗口模式

多窗口模式的生命周期:并不会改变原有生命周期,用户最近与哪个活动进行交互即设置为运行状态,将另外一个活动设置为暂停状态

进入到多窗口模式和横竖屏的切换默认是会重新创建活动

生命周期:

  1. 先启动一个活动,onCreate()、onStart()、onResume()方法依次执行
  2. 进入到多窗口模式 onPause()、onStop()、onDestroy()、onCreate()、onStart()、onResume()、onPause()
  3. 选中另外一个程序进入多窗口模式 另外一个活动 onCreate()、onStart()、onResume()方法依次执行
  4. 此时操作第一个活动,第一个活动执行 onResume()方法,另外一个活动执行 onPause()方法
    如果不想在进入多窗口模式时或横竖屏切换活动被重新创建:
    在Manifest文件中 activity标签中配置 android:configChanges=“orientation|keyboardHidden|screenSize|screenLayout”
    禁用多窗口模式:在Manifest文件 application或activity标签中 配置 android:resizeableActivity=“false”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值