Android基础知识

转自: https://blog.csdn.net/yuzhiqiang_1993/article/details/72675497

Activity相关

Activity是四大组件之一,应该是我们开发中接触最多的组件了吧。那么问题来了!


什么是Activity?
Activity是Android中的一个组件,提供了一个界面用于和用户交互,使用户可以在界面上进行点击、滑动等操作。


Activity的四种状态
running / paused / stopped / killed

running: 表明Activity处于活动(完全可见)状态,用户可以与屏幕进行交互,此时,Activity处于栈顶。
paused: 表明Activity处于失去焦点的状态(例如:被非全屏的的Activity覆盖),此时用户无法与该Activity进行交互。
stopped: 表明activity处于不可见的状态(例如:被另一个Activity完全覆盖)。
killed: 表明Activity被系统回收了,


Activity生命周期

首先来一张经典的图:
[图片上传失败...(image-e3b31c-1532583103079)]

Activity生命周期大致可以分为四个场景:

1.Activity启动–>onCreate()–>onStart()–onResume();
onCreate是Activity被创建的时候调用,是生命周期的第一个方法,在这里我们可以做一些初始化操作。
onStart表明Activity正在启动,此时处于用户可见状态,但是并不能与用户交互
onResume表明Activity已经处于前台状态,可以与用户交互了。

2.点击Home键–>onPause()–>onStop()
onPause:表明Activity处于paused状态,此时Activity无法与用户交互
onStop:一般在onPause后面执行,表明Activity处于完全不可见的状态。

3.点击home后再次回到程序时–>onRestart()–>onStart()–>onResume()
onRestart:表明Activity正在重新启动,从不可见状态变为可见状态

4.退出当前Activity–onPause()–>onStop()–>onDestory()
onDestory:表明Activity正在被销毁,是整个生命周期方法中的最后一个方法,在该方法中我们可以做一些资源回收的工作。


android中的进程优先级

前台/可见/服务/后台/空

前台:包含正在处于和用户交互的Activity或者是前台Activity绑定了service
可见:activity处于可见状态但不可与用户进行交互
服务:包含一个service服务的进程
后台:处于不可见的状态下(比如按了home键)
空:没有活跃的组件 知识为了缓存的目的存在的,随时都可能被系统杀掉


Android任务栈
用于存储Activity,当用户启动Activity或者退出Activity的时候,都会在栈中做一些添加或删除的操作。


Activity启动模式
1.standard
默认的启动模式,每次启动Activity的时候都会创建一个新的实例。不会复用Activity,对内存消耗较大。

2.singleTop
栈顶复用模式,如果要创建的Activity已经在栈顶的话,那么不会重新创建,直接复用,否则,仍然会重新创建。

3.singletask
栈内复用模式,如果要创建的Activity在栈内已经存在的话,不会重新创建,直接复用栈内存在的Activity,且会调用onNewIntent()方法,并且将该Activity以上的所有的Activity销毁。

4.singleInstance
单一实例,独享一个任务栈,整个手机操作系统里面只有一个实例存在。用的较少。


scheme跳转协议
android中的scheme是一种页面内跳转协议,通过自定义的scheme协议,可以方便的跳转app中的各个页面。通过scheme协议,服务端可以定制化告诉App跳转到哪个页面,可以通过通知栏消息定制化跳转页面,也可以通过H5页面跳转页面等。


Fragment相关

fragment在平时项目开发中用的也非常多,是Android3.0后引入的,起初是为了在大屏幕上更灵活的去展现ui。现在通常使用的方式是fragment+viewpager. fragment有自己的生命周期,必须依附Activity。


Fragment加载到Activity的两种方式

1.静态加载,在布局中加载
2.动态加载,在代码中加载(用的较多)
[图片上传失败...(image-2b101e-1532583103079)]

fragment经常和viewpager一起使用,不可避免的我们就会接触到FragmentPagerAdapter和FragmentStatePagerAdapter。

FragmentPagerAdapter和FragmentStatePagerAdapter有什么区别呢?
FragmentStatePagerAdapter在切换的时候会回收fragment
而FragmentPagerAdapter在切换时会将fragment与viewPager分离,并保存fragment的ui信息,
相比之下FragmentStatePagerAdapter更节省内存。所以在,在fragment比较多的时候推荐使用FragmentStatePagerAdapter。


Fragment的生命周期
Fragment是必须依附于Activity的,因此Activity的生命周期会直接影响到Fragment的生命周期。

[图片上传失败...(image-a18251-1532583103079)]

详细的生命周期我们来看下面这张图:

[图片上传失败...(image-cd12b0-1532583103079)]

由图片我们可以看整个fragment和Activity的生命周期执行顺序

fragment从创建到创建完成:

1.调用fragment中的onAttach()                fragment与Activity发生关联时调用
2.调用fragment中的onCreate()                创建fragment时调用
3.调用fragment中的onCreateView()            绘制fragment视图时调用
4.调用fragment中的onViewCreated()           界面绘制完成后调用
5.调用activity中的onCreate()                activity创建了
6.调用fragment中的onActivityCreated()       在activity的onCreate()方法之后调用,表明activity已经绘制完成
7.调用activity中的onstart()                 表明activity可见了
8.调用fragment中的onstart()                 activity可见后调用fragment中的onstart(),表明fragment也可见了
9.调用activity的onresume()方法               表明activity可以跟用户交互了
10.调用fragment的onResume()方法              此时,fragment也可以与用户进行交互了,到此为止,fragment完全初始化完毕了。

fragment的销毁过程:

1.调用fragment中的onPause()             此时fragment不可与用户交互
2.调用activity中的onPause()             此时activity不可与用户交互
3.调用fragment中的onStop()              此时fragment不可见
4.调用activity中的onStop()              此时activity不可见
5.调用fragment中的onDestoryView()       fragment视图被移除调用
6.调用fragment中的onDestory()           fragment销毁时调用
7.调用fragment中的onDetach()            fragment与activity解除关联时调用
8.调用activity中的ondDestory()          activity销毁

fragment通信

1.fragment调用Activity中的方法
通过getActivity()调用

2.在Activity中调用Fragment中的方法
需要在fragment类中定义一个接口并在Activity中实现它。Fragment在onAttach()回调函数中获取接口的具体实现的对象。然后,fragment就可以调用接口中的方法实现与Activity的通信。

3.在Fragment中调Fragment中的方法
通过getSupportFragmentManager().findFragmentById()


FragmentManager中的add,remove和replace
一般我们两种模式,一种是将fragment添加(add)到容器中,控制其隐藏和显示。这种模式不会销毁fragment。
另一种就是替换(replace)这种方法会把之前的fragment销毁掉。


Service相关

service是四大组件之一,用的地方也很多。可以在后台执行一些逻辑。


什么是Service
Service是一种能在后台执行耗时任务的没有界面显示的组件。需要注意的是Service和BroadCastReceiver都是运行在主线程的,所以,Service本身不能做耗时操作,而是通过子线程去完成!


Service和Thread的区别
详细可以看这篇博客service和thread的区别 讲的非常仔细。

在这里做个总结:
Thread和Service实际上是没有任何关系,只不过因为字面上的意思,我们可能会误解为Service可以执行耗时任务的,实际上Service是运行在主线程上的,也就是说,Service本身并不能做耗时操作,一般都是在Service中启线程去执行耗时任务。

Thread是程序执行的最小单元,是独立与Activity运行的,也就是说,如果我们在Activity中启线程去执行任务,即使这个activity被销毁了,该任务也会继续执行。
而Service是Android中一种机制,在一些运行在后台的不需要界面的地方可以使用Service。


Service的生命周期
onbind/onCreate/onStartCommand/ondestory

onBind(): 该方法返回的是一个IBinder接口,当我们使用bindService的时候才会被调用
onCreate(): 服务首次创建时调用,注意,只有service第一个被创建时才会调用
onStartCommand(): 每次调用startService的时候都会执行该方法,该方法有一个int类型的返回值
[图片上传失败...(image-fc6846-1532583103078)]

分别是:START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。
START_STICKY:”粘性的”,如果service进程被意外kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

onDestory(): 服务销毁时调用,在这里可以做一些资源回收操作。


Service的两种启动方式

startService 和 bindService

startService
1.定义一个类继承自Service
2.在清单配置文件中声明
3.使用Context.startService(Intent)启动Service
4.调用Context.stopService(Intent)停止Service

 Intent intent = new Intent();
 intent.setClass(activity, UpdateApkService.class);
 activity.startService(intent);//开启服务

执行startService时,Service会经历onCreate->onStartCommand。当执行stopService时,直接调用onDestroy方法。调用者如果没有stopService,那么即使Activity被销毁了,Service也会继续执行,下次调用者再起来仍然可以stopService。

bindService
1.创建一个类继承自Service,并在类中创建一个实现IBinder接口的实例对象并提供公共方法。


    /*这里定义一个类  用于返回Service*/
    public class MyBinder extends Binder {
        public MyService getService() {
            return MyService.this;
        }

    }
    /*提供一个公共方法*/
    public Date getTime(){
        return new Date();
    }

2.在onBind()中返回自定义的IBinder实例

  private MyBinder myBinder=new MyBinder();

    @Override
    public IBinder onBind(Intent intent) {
        return myBinder;
    }

3.在需要调用的地方,从onServiceConnected中获取IBinder实例并调用公共方法

  sc = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.i("aaa","onServiceConnected");
                MyService.MyBinder myBinder = (MyService.MyBinder) service;
                Date date = ((MyService.MyBinder) service).getService().getTime();
                Log.i("aaa",date.toString());
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };

        Intent intent = new Intent(this, MyService.class);
        bindService(intent, sc, BIND_AUTO_CREATE);

执行bindService时,Service会经历onCreate->onBind。这个时候调用者和Service绑定在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了),Service就会调用onUnbind->onDestroy。这里所谓的绑定在一起就是说两者共存亡了。


BroadcastReceiver

四大组件之一,在Android中,Broadcast是一种广泛运用在应用程序之间传输信息的机制,Android中我们要发送的是一个intent,intent可易携带我们需要传输的数据。


广播的使用场景
1.同一app中不同组件之间的数据传递
2.不同app之间组件的数据传递


广播的种类

1.普通广播 Context.sendBroadcast
2.有序广播 Context.sendOrderedBroadcast 根据优先级传播,优先级高的接收器和一阻止继续传播活修改数据
3.本地广播 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); lbm.sendBroadcast(new Intent(LOCAL_ACTION)); 只会在应用内部传播,相对来说数据安全。


广播的注册方式

1.静态注册 在清单配置文件中声明,即使进程被杀死,该广播仍然运行

<receiver android:name=".MyReceiver">  
            <intent-filter>  
                <action android:name="android.intent.action.MY_BROADCAST"/>  
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>  
        </receiver>  

2.动态注册 在代码中注册,受activity生命周期的影响。

MyReceiver receiver = new MyReceiver();  

IntentFilter filter = new IntentFilter();  
filter.addAction("android.intent.action.MY_BROADCAST");  

registerReceiver(receiver, filter);  

内部实现机制
1.自定义BroadcastReceiver,重写onReceive()方法
2.通过Binder机制向AMS(Activity Manager Service)进行注册
3.广播发送者通过Binder机制向AMS发送广播
4.AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadCastReceiver相应的消息循环队列中
5.消息循环执行拿到广播,回调BroadCastReceiver中的onReceive()方法。


LocalBroadcastManager
1.使用LocalBroadcastManager发送的广播只能在app内部传播,因此数据传输很安全。
2.比系统广播更加高效,底层是通过Handler发送message实现的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容