Android基础学习整理知识点

注:本文内容有自己理解部分,若有不对的地方,欢迎指出。

Android基础学习整理知识点_第1张图片

 

Android四大组件

Activity

什么是Activity?

 

是应用程序的组件,用于显示用户界面,可以与用户交互完成相关的操作。App中可以有很多个Activity。

Activity存储于android系统的返回栈(back stack)中,特点先进先出(返回键或finish()出栈)。

 

Activity的几种状态

 

Activity状态

说明

运行状态

处于返回栈栈顶,用户可见,能与用户交互。

暂停状态

不处于栈顶,可见;例如、弹出窗口页面后。

停止状态

不处于栈顶,不可见

销毁状态

从栈中移除。

 

Activity的生命周期

Android基础学习整理知识点_第2张图片

Activity各生命周期方法回调时期与页面状态

生命周期方法

Activity页面状态

方法体内容

onCreate

不可见状态

第一次创建后调用,设置布局、初始化组件、注册需要的广播接收者和数据绑定。

onStart

可见状态,此时不能与用户交互

部分资源(需要更新的)的加载,可以检测设置数据对象是否为空等。

onResume

可见状态,当前界面可以进行交互,activity为栈顶

大部分核心功能在此方法中实现。

onPause

可见状态,此时activity正在停止

数据存储、动画停止、资源回收。

onStop

不可见状态,activity完全停止或完全被覆盖

资源释放操作,不做耗时操作。

onDestroy

Activity销毁

回收工作和最终资源释放

onRestart

Activity重新启动时(后台回到前台,新act返回旧act)

恢复数据操作。

可归结三个关键周期:

从onCreate到onDestroy(整个的生命周期)

从onStart开始到onStop结束(可见的生命周期)

从onResume开始到onPause结束(前台的生命周期)

 

常见操作中Activity生命周期回调流程

 

正常启动:onCreate() -> onStart() -> onResume()

正常退出:onPause() -> onStop() -> onDestroy()

横竖屏切换:onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onResume()

解决方法:在AndroidManifest.xml中的

添加configChanges = “keyboardHidden|screenSize|orientation”

或添加screenOrientation = landscap此方式适合游戏类应用。

        



            

                

                

            

        

 

当A跳转到B,并按下返回键

A:onCreate -> onStart -> onResume ->onPause

B:onCreate -> onStart -> onResume

A:onStop

当按下返回键:

B:onPause

A:onRestart -> onStart -> onResume

B:onStop -> onDestory

Android基础学习整理知识点_第3张图片

 

按下Home键

onPause -> onStop

从后台回来:

OnRestart -> onStart -> onResume

Android基础学习整理知识点_第4张图片

 

Activity的注册

Activity需要在AndroidManiFest.xml中进行配置完成注册。

        



            

                

                

            

        

 

Activity间的跳转方式

 

显示跳转:需要知道activity的类名。适合应用内跳转。

 

Intent intent = new Intent(this,SecondActivity.class);

startActivity(intent);

 

隐式跳转:要知道activity的 意图过滤器中的action和Category或data属性。适合应用间的跳转。

 

      

            

                

                

                

            

        
    public void toBActivity(View view){

        Intent intent = new Intent();

        intent.setAction("My_Action");

        intent.addCategory("MyCategory");

        startActivity(intent);

    }

 

注:系统会默认为intent中添加“android.intent.category.DEFAULT”所以为能够正常采用隐式跳转必须设置category有DEFAUL。

 

Activity 的四种启动模式

 

中的launchMode来配置

standard(标准)模式:也是Activity的默认的模式,每次启动Activity都会有新的Activity实例进入栈顶,不管是栈顶还是栈内,有多少个同样的实例都会被创建。

singleTop(栈顶复用)模式:和standard一样 ,不过Activity实例在栈顶就不再创建,复用已有。

singleTask(栈内复用)模式:如果有Activity实例在栈顶就不会创建新的实例,复用已有的Activity即可;若在实例之上有其他Activity的实例则弹出其他的Activity实例,复用已有Activity。

singleInstance(单实例)模式:保证系统无论从哪个Task启动Activity都只会创建一个Activity实例,并将它加入新的Task栈顶 也就是说被该实例启动的其他Activity会自动运行于另一个Task中。已存在无论在那个栈都会到前台显示。 singleInstance的Activity位于栈顶,因为它所在的Task仅有它一个Activity。

 

四种启动模式的应用场景

        standard模式:默认启动模式,大部分页面都是这些模式。

        singleTop模式:用于通知栏,推送消息页面。

        singleTask模式:应用首页,首页只有一个。

        singleInstance模式:独立栈操作的应用,启动与程序分离情况,闹钟的提醒、打开其他应用。

 

问题思考

若跳转到一个是窗口的Activity,生命周期回调情况?

A:onPuse

B:onCreate -> onStart -> onResume

点击返回:A: onResume

解释:因为A页面还是可见的,不会调用onStop。

 

锁屏/解锁生命周期回调情况?

锁屏:onPause -> onStop

解锁:onRestart -> onStart -> onResume

Android基础学习整理知识点_第5张图片

 

内存不足时候杀死Activity的顺序?

后台(用户不可见) > 可见不能操作 > 前台

 

在隐式跳转中,若目标activity没有在意图过滤中没加category会发生什么?

例子:

   

            android:exported="true">

           

               

           

 

        Intent intent = new Intent();

        intent.setAction("My_Action");

        startActivity(intent)

 

54035492e4834b09a30e109c1fe834c2.png

 

 

在隐式跳转中能匹配到两个Activity是否能够编译通过?运行结果什么样?

可以编译通过,会让你选择进入哪个页面。

Android基础学习整理知识点_第6张图片

 

Activity结束和进程结束方式有哪些?其他activity结束进程会发生什么?

 

Activity结束自己finish();

结束整个进程android.os.Process.killProcess(android.os.Process.myPid());System.exit(0);

注:程序主页面结束进程会退出程序,跳转到其他页面结束进程,结束后会自己启动。

 

Service

 

是什么?

可长期运行在后台没有界面的组件。可由其它组件启动,组件通过绑定可以与其交互。

 

Service类型

前台服务

        执行用户能注意到的操作。音乐播放,用户可以通过通知栏知道当前播放的内容。

后台服务

        执行用户不会注意到的操作。上传、定时关闭

绑定服务

        绑定后可以与绑定组件进行交互。

 

Service的注册

与Activity类似需要在AndroidManifest.xml中进行注册。

还能写其他属性android:permission是权限声明,android:process设置具体的进程名称。

 

Service生命周期

Android基础学习整理知识点_第7张图片

 

两种绑定方式及其生命周期

        startService方式:onCreate -> onStartCommad -> onDestory(想要启动一个后台服务进行某项任务)

        bindService方式:onCreate -> onBind -> onUnbin -> onDestroy(需要与服务进行通信)

通过bind方式开启的服务会与调用者的生命周期进行绑定,并能进行通信,单启动时,调用者销毁服务也会销毁,start开启的不会销毁但不会通信。当所有的客户端都和service解除绑定后,系统会销毁service。(除非service也被startService()方法开启)

        混合开启服务方式:onCreate-> onStartCommad -> onBind (想长期运行并通信,调用者结束服务不结束)

开启服务,能够确保服务长期运行

 绑定服务,能够通信(只把Service的IBinder对象传递给Activity,不会绑定两个对象的生命周期)

退出activity,要解绑服务释放资源

 

Service一般在主线程中,注意不要进行耗时操作。

 

重复调用startService或者bindService

 

        重复调用startService会重复执行onStartCommand,onCreate只会执行一次。

        重复调用bindService时只回调一次onBind,之后只会直接把IBinder对象传递给后来的客户。

 

如果Service已经由某个客户端通过StartService()启动,接下来由其他客户端 再调用bindService()绑定到该Service后调用unbindService()解除绑定最后在 调用bindService()绑定到Service的话,此时所触发的生命周期方法如下:

 

        onCreate( )->onStartCommand( )->onBind( )->onUnbind( )->onRebind( )

 

问题思考

Service与Thread线程的区别?

        两者没有太大关系,Thread是线程,程序执行的最小单元,分配CPU的最小单元,可以运行耗时操作。Service是安卓的组件,运行在主进程的主线程上。不同的Activity中无法对同一线程进行控制。

 

只要回调了onStartCommad服务就会长期运行,尽管调用者销毁。(没有服务内容)65s后会自动销毁。(Android12)

0b78f70b37d642bb994bb0a7075802df.png

 

Service应用场景

        音乐播放、下载、上传大文件、定时关闭应用的功能。

 

Service里可以弹Toast吗?为什么?

        可以,一它在主线程,可以刷新UI,二是context的子类有上下文。有些时候就可以通过toast告诉用户发生了什么事。

 

一个服务可以被多个客户端(Activity)绑定吗?

        可以,但只有第一个组件绑定时才调用onBind(),其它的只是传递个IBinder对象给绑定组件以便通信。

为什么需要前台服务?

        若服务在后台的运行,当内存不足时可能会优先对其进行回收,为了能够保持服务长期工作可置为前台服务。

 

Broadcast

什么是?

        广播是程序组件之间的传输消息的机制,广播的内容是一个intent,在其中携带数据,他没有用户界面。

        同一APP中不同组件传输,不同APP组件间传输消息。

            默认情况下广播接收者运行在UI线程中。

 

广播的类型

        标准广播:异步执行,发出后接收者几乎同一时刻收到广播。

        有序广播:同步执行,同一时间只有一个接收者能收到,这个接收者可以选则停止,执行完逻辑后继续传递,还可修改广播内容。

            粘性广播:粘性广播发送后在没有找到任何接收方的情况下会一直等待,接收者重建会接收到广播。(确保重要的状态改变后的信息被持久保存,并且能随时广播给新的广播接收器)

            系统广播:有系统程序发出的广播,是标准广播。主要涉及到手机的基本操作

action                                         触发时机

android.net.conn.CONNECTIVITY_CHANGE       网络连接发生变化

android.intent.action.SCREEN_ON                屏幕点亮

android.intent.action.SCREEN_OFF               屏幕熄灭

android.intent.action.BATTERY_LOW           电量低,会弹出电量低提示框

android.intent.action.BATTERY_OKAY          电量恢复了

android.intent.action.BOOT_COMPLETED        设备启动完毕

android.intent.action.DEVICE_STORAGE_LOW   存储空间过低

android.intent.action.DEVICE_STORAGE_OK      存储空间恢复

android.intent.action.PACKAGE_ADDED          安装了新的应用

android.net.wifi.STATE_CHANGE                 WiFi 连接状态发生变化

android.net.wifi.WIFI_STATE_CHANGED       WiFi 状态变为启用/关闭/正在启动/正在关闭/未知

android.intent.action.BATTERY_CHANGED      电池电量发生变化

android.intent.action.INPUT_METHOD_CHANGED      系统输入法发生变化

android.intent.action.ACTION_POWER_CONNECTED 外部电源连接

android.intent.action.ACTION_POWER_DISCONNECTED    外部电源断开连接

android.intent.action.DREAMING_STARTED             系统开始休眠

android.intent.action.DREAMING_STOPPED             系统停止休眠

android.intent.action.WALLPAPER_CHANGED         壁纸发生变化

android.intent.action.HEADSET_PLUG               插入耳机

android.intent.action.MEDIA_UNMOUNTED             卸载外部介质

android.intent.action.MEDIA_MOUNTED               挂载外部介质

    //发送标准广播

private void sendSecondBroadcast() {

        Intent intent = new Intent();

        intent.setAction("com.archermind.mybroadcast.UNORDER_BROADCAST");

        sendBroadcast(intent);

    }
    //发送有序广播

public void sendOrderBroadcast(View view){

        Intent intent = new Intent();

        intent.setAction("com.archermind.mybroadcast.ORDER_BROADCAST");

        Bundle bundle = new Bundle();

        bundle.putInt("money", 1000 * 500);

        sendOrderedBroadcast(intent, "com.archermind.mybroadcast.MY_PERMISSION",null,null,1,"1000",bundle);

    }

 

广播接收者注册

 

动态注册:IntentFilter添加Action,调用registerReceiver,不用时记得取消注册。Activity启动后才能注册。

静态注册:在AndroidManiFest.xml中采用标签配置注册。应用不启动就可以接收广播。

注:广播发送给静态注册的接收者时需要为intent设置component包名和路径;发送给动态注册的不需要设置,设置反而接收不到。

//向静态注册接收者发送广播

Intent intent = new Intent();

intent.setAction("com.archermind.mybroadcast.SEND_BROADCAST_ON_CLICK");

intent.setComponent(new ComponentName(getPackageName(),"com.archermind.mybroadcast.SendBroadcastActivity$InnerReceiver"));

intent.putExtra("Content","点击发送广播");

sendBroadcast(intent);

//向静态注册接收者发送广播

Intent intent = new Intent();

intent.setAction("com.archermind.mybroadcast.SEND_BROADCAST_ON_CLICK");

intent.setComponent(new ComponentName(getPackageName(),"com.archermind.mybroadcast.SendBroadcastActivity$InnerReceiver"));

intent.putExtra("Content","点击发送广播");

sendBroadcast(intent);

 

广播中的权限(广播安全性问题的解决)

 

        谁有权接收我的广播:广播发送者需要在AndroidManifest.xml中设置

        谁有权给我发送广播:静态注册中的加上permission属性。

 

//广播发送者的AndroidManifest.xml中

//广播的发送

sendBroadcast(intent,"com.archermind.mybroadcast.MY_PERMISSION");

sendOrderedBroadcast(intent, "com.archermind.mybroadcast.MY_PERMISSION",null,null,1,"1000",bundle);

//谁有权给我发广播,动态广播接收者的注册

registerReceiver(receiveBroadCast, intentfilter, "com.archermind.mybroadcast.MY_PERMISSION" ,null);

//谁有权给我发广播,静态广播接收者的注册

       

            android:exported="true"

            android:permission="com.archermind.mybroadcast.MY_PERMISSION">

           

               

           

       

 

问题思考

 

BroadCastReceiver中有那些应用场景?

        APP内部消息通信。

        不同APP之间的消息通信。

        接收系统发出的设备信息。

 

广播优先级对无序广播生效吗?

        优先级对无序广播生效

 

动态注册谁的优先级更高?

        一自己设置优先级,二谁先注册谁高。

 

如何判断当前广播接收者收到的广播是有序还是无序?

        在onReceive中调用isOrderedBroadcast()

 

BroadcastReceiver中为什么不能执行耗时操作?

 

  • BroadcastReceiver一般处于主线程中,时间超过10s会报ANR错误。
  • BroadcastReceiver启动较快,若进程中只有一个接收者并开了耗时的子线程,系统会认为是空进程,系统会优先杀死。

 

前台广播后台广播?

前台广播对应前台队列,后台广播对应后台队列。可以通过设置Intent.FLAG_RECEIVER_FOREGROUND属性来将广播定义为前台广播,如果未定义,默认使用后台广播。前台广播超时时间是10s,后台是60s。

 

ContentProvider内容提供者

什么是?

        实现数据共享的重要组件,自身和其他应用所存储数据的访问,并提供与其他应用共享数据的方法。

使用场景:

        访问其他应用中的现有的内容提供者;在应用中创建新的内容提供程序,从而实现与其他应用的内容共享。

ContentProvider的注册

        需要在AndroidManifest.xml中进行注册

  

 

ContentProvider执行过程

Android基础学习整理知识点_第8张图片

 

ContentProvider实现数据共享

 

当一个应用程序要把自己的数据暴露给其他程序时,通过ContentProvider来实现。

其他应用可以通过ContenrResolver来操作ContentProvider暴露的数据。

定义自己的ContentProvider类,该类需要继承Android系统提供的ContentProvider基类。

在Manifest.xml 文件中注册ContentProvider,(四大组件的使用都需要在Manifest文件中注册) 注册时需要绑定一个URL

 

调用Activity的ContentResolver获取ContentResolver对象

调用ContentResolver的insert(),delete(),update(),query()进行增删改查。

一般来说,ContentProvider是单例模式,也就是说,当多个应用程序通过ContentResolver来操作ContentProvider提供的数据时,ContentResolver调用的数据操作将会委托给同一个ContentResolver。

 

ContentProvider、ContentResolver之间的关系?

 

        ContentProvider内容提供者, 用于对外提供数据。

        ContentResolver内容解析者, 用于获取内容提供者提供的数据。

        一个应用可以实现ContentProvider来提供给别的应用操作,通过ContentResolver来操作别的应用数据。

 

内容URI模式

Android基础学习整理知识点_第9张图片

 

        为表使用的内容 URI 模式是 content:///

        为单个行使用的内容 URI 模式则是 content:////

 

问题思考

 

ContentProvider和sql的实现上的有什么差别?

ContentProvider屏蔽了数据存储细节,使用者只需要关心操作数据的uri,它还可以实现不同app之间的共享。Sql只能增删改查本应用数据库。

 

多个进程同时调用一个ContentProvider的query获取数据,ContentProvider是怎么反应的?

多进程访问ContentProvider请求会按队列的形式进入ContentProvider,在一个进程中线程是互斥的。

四大组件小结

四大组件都是系统提供的,所以在写代码时都是要继承系统相应的类的。

生命周期方法都是系统管理的,尽量避免自己调用其系统方法。

四大组件都是要注册的,其中Broadcast能用动态注册,其他的都在AndroidManifest.xml中注册的。

其中Activity是有用户界面,其他组件没有。

它们一般都运行在主线程中,所以尽量不把耗时操作写在其中,在主线程中可以修改UI。

ANR报错

Input dispatching timed out

输入时间分发超过5s,包括按键和触屏事件

Broadcast of Intent

前台广播需要在10s,后台广播需要在60s

executing service

前台服务需要在20s,后台则需要在200s

ContentProvider

publish执行未在10s内完成?

Service.startForeground()

应用调用startForegroundService,然后5s内未调用startForeground出现ANR或者Crash

 

Fragment

 

什么是?

相当于自定义的组件(一个小的Activity),在需要Fragment的Activity的.xml中写上就会显示其内容。有自己的生命周期并依赖于Activity,Activity销毁fragment也销毁。

 

Fragment的生命周期

Android基础学习整理知识点_第10张图片

 

Fragment的创建方式

静态加载Fragment

Android基础学习整理知识点_第11张图片

 

动态加载Fragment

Android基础学习整理知识点_第12张图片

 

注:容器是布局,组件的话只能添加或替换一次。

FragmentManager对象(管理fragment)

findFragmentById()

获取指定的fragment

popBackStack()

弹出后台Fragment

addToBackStack()

加入栈

FragmentTransaction对象(事务管理)

add()

向Activity中添加一个Fragment

remove()

移除一个已存在的Fragment

replace()

替换一个已被添加进视图容器的Fragment

show()hide()

展示一个fragment

Android基础学习整理知识点_第13张图片

 

Fragment传递数据给Activity(F的数据显示到A的UI中)(回调接口方式)

三种调用方式

Android基础学习整理知识点_第14张图片

​​​​

同步调用:一种阻塞式调用,A的方法中调用B的方法,需要等待B返回结果,A才能继续进行。

异步调用:类似消息和事件处理机制,A通知B后,然后各自运行。

回调:双向的调用模式,A要调用B(A需要F的数据),B在执行完又要调用A。

//在fragment中创建发送信息接口

public class Fragment1 extends Fragment {

    oneSendValue mMySendValue;

    … …

    public interface oneSendValue{

        void oneSend(String s);

}

… …

}

 

//在Activity中实现这个接口

public class MainActivity extends AppCompatActivity implements Fragment1.oneSendValue {

……

    @Override

    public void oneSend(String s) {

        textView.setText(s);

}

……

}

 

//在fragment调用实现的接口函数

public class Fragment1 extends Fragment {

    oneSendValue mMySendValue;

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        ……

        Button button=view.findViewById(R.id.button_my);

        button.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View view) {

                String s=editText.getText().toString();

                mMySendValue.oneSend(s);

            }

        });

        return view;

}

……

}

 

问题思考

动态加载成功后进行横竖屏切换Fragment生命周期函数?

走销毁再创建的生命周期

Android基础学习整理知识点_第15张图片 

Fragment堆积怎么解决?

堆积出现出原因:每次加载时都是new的新的Fragment对象,动态加载到Activity中。

加载语句为:

getFragmentManager().beginTransaction().add(R.id.frameLayout1,new BlankFragment1()).commit();

解决方法:将Fragment抽出为成员变量,再加载前判空,若不为空对象show()出来。

        if(blankFragment2 == null){

            blankFragment2 = new BlankFragment2();

           fragmentTransaction.add(R.id.frameLayout2,blankFragment2).commit();

        } else {

            fragmentTransaction.show(blankFragment2);

        }

 

多线程

Android的应用与用户的交互大多都是在主线程中完成(UI显示、界面交互),为了用户体验,耗时操作就不能在主线程中(Android有个ANR报错),所以耗时的操作就要在线程中进行。

 

Thread类

//两个继承Thread的类

private class MyThread1 extends Thread{

        private int ticket = 3;

        private String name ;

        public MyThread1(String name){

            this.name = name;

        }

        public void run(){

            while(ticket > 0){

                ticket--;

                System.out.println(name + "卖掉了1张票,剩余票数为:"+ticket);

                try {

                    Thread.sleep(1000);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        }

}

private class MyThread2 extends Thread{……}

 

//调用的地方

   public void startSellTicket1(View view) {

        MyThread1 myThread1 = new MyThread1("张三");

        MyThread2 myThread2 = new MyThread2("李四");

        myThread1.start();

        myThread2.start();

    }

运行结果

Android基础学习整理知识点_第16张图片

 

是Java中实现多线程的具体类,封装了线程操作。

线程对象:运行线程的实体,线程对象是控制线程行为的唯一手段。

特点:实现简单 只需要继承Thread类和复写run()方法;局限性大(Java是单继承)、不适合资源共享(一个线程=一个对象,相对独立)、消耗资源(一个线程=一个耗时任务,多此创建多次销毁)。

注:Tread线程不能操作UI。

82cf6a432f3545f08ca53bc6f753799b.png

 

Runnable类

    //实现Runnable接口的类

private class MyThread3 implements Runnable{

        private int ticket = 9;

        @Override

        public void run() {

            while(ticket > 0){

                ticket--;

                System.out.println(Thread.currentThread().getName() + "卖掉了1张票,剩余票数为:" + ticket);

                try {

                    Thread.sleep(1000);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        }

    }

 

    public void startSellTicket2(View view) {

        MyThread3 myThread3 = new MyThread3();

        new Thread(myThread3,"张三").start();

        new Thread(myThread3,"李四").start();

    }

运行结果

Android基础学习整理知识点_第17张图片 

它是一个多线程相关的抽象接口,仅定义了一个run()方法。

特点:适合资源共享(Runnable的代码可被多个先线程共享,适合多个线程处理同一资源)灵活(一个类可以实现多个接口)。

 

Thread类和Runnable的区别?

继承和接口的区别

class Thread implements Runnable{}

Thread和Runnable的实质是继承关系,没有可比性。无论使用Runnable还是Thread,都会new Thread,然后执行run方法。用法上,如果有复杂的线程操作需求,那就选择继承Thread,如果只是简单的执行一个任务,那就实现runnable

AsyncTask

是什么?

一个Android封装好的轻量级异步类。抽象类。

 

AsyncTask相关执行流程

Android基础学习整理知识点_第18张图片

 

注:Task的实例必须在主线程中创建;execute方法必须在主线程中调用;不要手动调用回调方法。一个Task实例只能执行一次,多次调用会有异常。

 

AsyncTask对象调用execute方法(可以传一个或多个参数)中调用onPreExecute(),然后是doInBackground(),在其中可以调用publishProgress(),doInBackground()的结果可以给onPostExecute(),在doBackground方法中,每次调用publishProgress方法都会触发onProgressUpdate()方法。

Handler

什么是?

Android系统中线程间传递消息的一种机制,线程间通信。(异步线程与主线程通信一般都有Handler)

 

Handler的引入

因为Android只允许UI线程中修改UI组件,Handler(发送与处理数据)可以解决周期性修改UI组件的属性。

 

Handler的执行流程

Android基础学习整理知识点_第19张图片

 

Looper

 

        每个线程只能够有一个Looper,管理MessageQueue,不断地从中取出Message分发给对应的Handler处理!

 

Message对象

        Message对象是封装了需要传递的数据给Handler处理。

        Message.what:标识一个Message对象。

        Message.obj:存储任意类型的Object对象。

 

线程池

 

频繁地为每一个任务创建一个线程,缺乏统一管理,降低性能,并且容易出现问题;线程池能对多线程进行同一管理,避免资源竞争中出现的问题;对线程进行复用;有完整的api操作方便。

 

线程池的执行过程

Android基础学习整理知识点_第20张图片

 

问题思考

Handler引起的内存泄露问题?

        当使用内部类(包括匿名类)来创建Handler的时候(内部类持有外部引用),Handler对象会隐式地持有Activity的引用。

        在请求网络过程中关闭了Activity,因为此时Handler又持有Activity的引用,就导致该Activity无法被收回,直至网络请求结束。

        解决方法:使用弱引用。

 

一个线程有几个Handler?

        可以有多个。

 

一个线程有几个Looper?如何保证?

 

        一个。Looper的构造只能通过Prepare()方法(同时会初始化一个消息队列),当调用后ThreadLocal中的get()方法检查ThreadLocalMap中是否已经set过Looper。

 

当Activity重新创建时,(非静态内部类)AsyncTask的Activity的引用无效,怎么处理?

        在Activity恢复时的对应方法重启 任务线程。

 

 

进程间通信

 

进程间通信方式:(file、内存共享)Binder机制,Bundle,Socket,AIDL,contentProvider

进程

进程是运行起来的程序,被加载到内存,进程独立运行,数据互不干扰。

 

        前台进程:正在交互的进程

        可见进程:可见不可操作

        服务进程:不可见、后台、正在忙碌

        后台进程:在后台,不做事

        空进程:缓存作用

 

Binder

是一种Android中实现跨进程通信的方式,是一种虚拟的的物理设备驱动。

普通进程间通信和采用Binder机制进程间通信。

普通进程间通信

Android基础学习整理知识点_第21张图片

 

Binder跨进程通信机制

Android基础学习整理知识点_第22张图片

 

ServiceManager进程 管理Service注册与查询,Binder驱动一种虚拟驱动(传递进程间的数据:通过内存映射;实现线程控制:采用Binder的线程池)。

Android基础学习整理知识点_第23张图片

 

 

Bundle

用于消息传递,以键值对的形式保存数据,可以传递基本数据类型,也可传递引用类型(要实现Serializable或Parcelable的接口)。

结合Intent对象实现传递。

 

Socket

套接字,来描述IP地址和端口,是通信的句柄,通信双方通过Socket对象获得通信信息。

Android基础学习整理知识点_第24张图片

 

问题思考

服务进程后台进程区别?

        调用startService方法启动的Service进程组件,没有与Activity绑定;不可见Activity,调用了onStop没有调用onDestroy

 

 

 

 

 

你可能感兴趣的:(android,学习)