Android 基础篇

Android 基础篇

1. Activity详细解析

  1. Android中的activity全都归属于task管理 。task 是多个 activity 的集合,这些 activity
    按照启动顺序排队存入一个栈(即“back stack”)。android默认会为每个App维持一个task来存放该app的所有activity,task的默认name为该app的packagename。

  2. 首先打开一个新的activity实例的时候,系统会依次调用 onCreate() -> onStart() -> onResume()
    然后开始running; running的时候被覆盖了(从它打开了新的activity或是被锁屏,但是它依然在前台运行, lost focus but is still visible),系统调用onPause();
    该方法执行activity暂停,通常用于提交未保存的更改到持久化数据,停止动画和其他的东西。但这个activity还是完全活着(它保持所有的状态和成员信息,并保持连接到窗口管理器);
    如果用户返回到onStop()状态的activity(又显示在前台了),系统会调用 onRestart() -> onStart()
    -> onResume() 然后重新running 在activity结束(调用finish ())或是被系统杀死之前会调用onDestroy()方法释放所有占用的资源

  3. activity生命周期中三个嵌套的循环:
    activity的完整生存期会在 onCreate() 调用和 onDestroy()调用之间发生。 
    activity的可见生存期会在 onStart() 调用和 onStop()调用之间发生。
    系统会在activity的整个生存期内多次调用 onStart() 和onStop(),
    因为activity可能会在显示和隐藏之间不断地来回切换。 
    activity的前后台切换会在 onResume() 调用和onPause() 之间发生。
    因为这个状态可能会经常发生转换,为了避免切换迟缓引起的用户等待,这两个方法中的代码应该相当地轻量化。

/**
     * 可能被回收内存前保存状态和信息,
     *
     * 在activity 可能被回收之前 调用,用来保存自己的状态和信息,
     * 以便回收后重建时恢复数据(在onCreate()或onRestoreInstanceState()中恢复)。
     * 旋转屏幕重建activity会调用该方法,但其他情况在onRause()和onStop()状态的activity不一定会调用。
     * @param outState
     * @param outPersistentState
     * 
     * 系统灵活的来决定调不调用该方法,但是如果要调用就一定发生在onStop方法之前,
     * 但并不保证发生在onPause的前面还是后面
     */
    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {

        //可能被回收内存前保存状态和信息,
        Bundle data = new Bundle();
        data.putString("key", "last words before be kill");
        outState.putAll(data);
        super.onSaveInstanceState(outState, outPersistentState);
    }
 /**
     * 判断是否有以前的保存状态信息
     * @param savedInstanceState
     * 
     * 这个方法在onStart 和 onPostCreate之间调用,在onCreate中也可以状态恢复,但有时候需要所有布局初始化完成后再恢复状态。
     * onPostCreate:一般不实现这个方法,当程序的代码开始运行时,它调用系统做最后的初始化工作。
     */
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        if(savedInstanceState!=null){ //判断是否有以前的保存状态信息
            savedInstanceState.get("Key");
        }
        super.onRestoreInstanceState(savedInstanceState);
    }
  1. 启动模式
  • “standard” (默认模式)
      当通过这种模式来启动Activity时, Android总会为目标 Activity创建一个新的实例,并将该Activity添加到当前Task栈中。这种方式不会启动新的Task,只是将新的 Activity添加到原有的Task中。
  • “singleTop”

该模式和standard模式基本一致,但有一点不同:当将要被启动的Activity已经位于Task栈顶时,系统不会重新创建目标Activity实例,而是直接复用Task栈顶的Activity。

  • “singleTask”

Activity在同一个Task内只有一个实例。如果将要启动的Activity不存在,那么系统将会创建该实例,并将其加入Task栈顶;

如果将要启动的Activity已存在,且存在栈顶,直接复用Task栈顶的Activity。

如果Activity存在但是没有位于栈顶,那么此时系统会把位于该Activity上面的所有其他Activity全部移出Task,从而使得该目标Activity位于栈顶。

  • “singleInstance”

无论从哪个Task中启动目标Activity,只会创建一个目标Activity实例且会用一个全新的Task栈来装载该Activity实例(全局单例).

如果将要启动的Activity不存在,那么系统将会先创建一个全新的Task,再创建目标Activity实例并将该Activity实例放入此全新的Task中。

如果将要启动的Activity已存在,那么无论它位于哪个应用程序,哪个Task中;系统都会把该Activity所在的Task转到前台,从而使该Activity显示出来。

  1. 开发中Activity的一些问题

一般设置Activity为非公开的

<activity  
...... 
android:exported="false" /> 

注意:非公开的Activity不能设置intent-filter,以免被其他activity唤醒(如果拥有相同的intent-filter)。

不要指定activity的taskAffinity属性

不要设置activity的LaunchMode(保持默认)

注意Activity的intent最好也不要设定为FLAG_ACTIVITY_NEW_TASK

在匿名内部类中使用this时加上activity类名(类名.this,不一定是当前activity)

设置activity全屏

在其 onCreate()方法中加入:

// 设置全屏模式
 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
 // 去除标题栏
 requestWindowFeature(Window.FEATURE_NO_TITLE);

通过配置不同的 action 可以改变Activity属性
例如想把Activity设置为打开图片资源类型的:

    <activity android:name=".SmsObserverActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
            </intent-filter>
        </activity>

2. Service详细解析

  1. 服务的分类

按运行分类

  • 前台服务

前台服务是指那些经常会被用户关注的服务,因此内存过低时它不会成为被杀的对象。 前台服务必须提供一个状态栏通知,并会置于“正在进行的”(“Ongoing”)组之下。这意味着只有在服务被终止或从前台移除之后,此通知才能被解除。   例如,用服务来播放音乐的播放器就应该运行在前台,因为用户会清楚地知晓它的运行情况。 状态栏通知可能会标明当前播放的歌曲,并允许用户启动一个activity来与播放器进行交互。

要把你的服务请求为前台运行,可以调用startForeground()方法。此方法有两个参数:唯一标识通知的整数值、状态栏通知Notification对象。例如:

Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),System.currentTimeMillis());

Intent notificationIntent = new Intent(this,ExampleActivity.class);

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(this, getText(R.string.notification_title),
        getText(R.string.notification_message), pendingIntent);
        
startForeground(ONGOING_NOTIFICATION, notification);

要从前台移除服务,请调用stopForeground()方法,这个方法接受个布尔参数,表示是否同时移除状态栏通知。此方法不会终止服务。不过,如果服务在前台运行时被你终止了,那么通知也会同时被移除。

  • 后台服务

IntentService详细解析
IntentService原理解析文章
ContentProvider实例详解
BroadcastReceiver详细解析
Android异步任务机制之AsycTask
Handler,Looper,MessageQueue关系
Android-SQLite的基本使用
Android系统相机与相册的使用
图片缓存原理
Android数据存储的五种方式
Android跟随手指移动的View
RecyclerView的使用
Android获取SHA1
Recyclerview和Listview的异同.md
初识ConstraintLayout
TabLayout记录
用SpannableString打造绚丽多彩的文本显示效果
解析ConstraintLayout的性能优势
Android新特性介绍,ConstraintLayout完全解析
Android新特性介绍,ConstraintLayout完全解析
Android 一个无限循环滚动的卡片式ViewPager

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值