Android 基础知识点_基于《第一行代码》

Android

四大组件

四大组件指Activity、Service、BroadcastReceiver、ContentProvider,这四大组件都需要在AndroidManifest文件中注册才可以使用。

Activity

什么是Activity?

  • 它是一种可以包含用户界面的组件,主要用于和用户进行交互。

Activity之间是如何进行数据传递的?

  • 六种传值方式
    通常采用对象序列化的方式进行传值,因为通常传递的内容不会是简单的字符串。

Activity的启动流程?

启动流程详解

在这里插入图片描述

Activity的生命周期?

  • 7个:onCreate() - onStart() - onResume() - onPause() - onStop() - onRestart() - onDestory()
    其中,
    用户可见可操作的阶段:onResume()
    界面可见或部分可见但不能进行操作:onPause()
    用户不可见的阶段:onStop()

相关问题
Activity A 弹出Dialog 的时候,Activity A 所经历的生命周期

  • Activity不会执行任何生命周期

Activity A 弹出Dialog ,Dialog中有按钮跳转到另一个Activity B

  • Activity A 执行:onPause()
    Activity B 执行 onCreate() ->onStart()-> onResume()
    Activity A 执行 onStop()

横竖屏切换的时候,Activity所经历的生命周期

  • ①如果该Activity未进行任何设置,则 横屏切换,会执行两次生命周期,竖屏切换,会执行一次生命周期
    ②如果设置 Activity 的 android:configChanges=“orientation” 时,切横、竖屏时只会执行一次生命周期
    ③如果设置 Activity 的android:configChanges=“orientation|keyboardHidden” 时,不会执行生命周期

活动状态

  • 运行状态:活动处于栈顶,用于用户交互
  • 暂停状态:活动不处于栈顶,但还是对用户可见,但不能进行操作,比如,一个Activity上面弹出一个dialog,则仍然可以看到dialog后面的activity,但此时的activity则处于暂停状态
  • 停止状态:活动不处于栈顶且不可见时
  • 销毁状态:当活动从返回栈中移除的后就变成销毁状态

Activity的几种启动方式?

  • Standard :默认的启动模式,每次启动活动,都是一个新的活动,并且放入 返回栈S中,不会在乎这个活动是否已经在返回栈中了
  • SingleTop :栈顶复用。在启动该活动的时候,如果发现该活动位于返回栈的栈顶,则直接使用它,不会再创建新的活动。
    注意:复用时,由于不会创建新的活动,所以也不会走完整的生命周期,而是调用onNewIntent()方法。
  • SingleTask:栈内复用。如果该活动不在栈顶,则清空该活动上的其他活动,弹出该活动。
  • SingleInstance:活动存放在另一个栈中。

BroadcastReceiver

定义:

  • Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的Broadcast进行过滤接受并响应的一类组件

特点:

  • 广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的。

三要素:

  • 广播(Broadcast) - 用于发送广播;
  • 广播接收器(BroadcastReceiver) - 用于接收广播;
  • 意图内容(Intent)-用于保存广播相关信息的媒介

类型

  • 标准广播和有序广播
  • 标准广播:异步执行的广播。所有广播接收器几乎在同一时间接收广播,他们之间没有接收顺序,这种广播的效率比较高,同时意味着它是无法进行截断的。

在这里插入图片描述

  • 有序广播:同步执行的广播,在广播发出之后,同一时刻只有一个广播接收器能够收到这条消息,广播接收器再根据业务逻辑判断是否继续传递广播还是进行拦截。
    在这里插入图片描述

广播接收器(BroadcastReceiver)

  • 对自己感兴趣的广播进行注册,这样当有响应的广播时,广播接收器就能接收到广播。

注册类型

  • 静态注册:在AndroidManifest.xml中注册,其中name 为自定义的广播接收器,action为我们要监听的广播类型,也可以自定义广播。
    在这里插入图片描述
  • 动态注册:在代码中注册为动态注册,动态注册,记得在activity销毁的时候,即onDestroy()中取消注册,unregisterReceiver()方法实现。
    在这里插入图片描述

相关问题:

广播的分类?

  • 有序广播和标准广播

广播的使用场景

  • 用于接收网络状态
  • 应用与应用之间的唤醒,比如淘宝唤醒支付宝支付
  • 组件间通信,电量不足的提示

广播使用的方式

  • demo1:发送静态注册自定义标准广播在这里插入图片描述在这里插入图片描述在这里插入图片描述
  • demo 2 发送静态注册自定义有序广播 结合demo1
  • 广播在MyBroadcastReceiver被截断,AnotherBroadcastReceiver则接收不到广播,如果需要常接受,则需去掉abortBroadcast()方法。 在这里插入图片描述在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • demo3 发送动态注册自定义本地标准广播
    tip:本地广播:未防止其他应用也接收到自己应用发送的自定义广播,
    在这里插入图片描述
    在这里插入图片描述

相关问题

在manifest 和代码中如何注册和使用BroadcastReceiver?

  • 看以上的静态注册和动态注册

本地广播和全局广播有什么差别?

  • 本地广播:
  • 只可以自己应用接收的广播
  • 防止自己发送的广播被其他应用所拦截
  • 防止接收垃圾广播攻击自己的应用
  • 全局广播:
  • 任何应用都可以接收到的广播

如何通过广播拦截和abort一条短信?

  • 看上面的demo2,采用有序广播进行发送,并拦截。

广播是否可以请求网络?

  • 可以,但需要在子线程中进行,主线程超过10s会造成ANR.

广播引起ANR的时间限制是多少?

  • 当BroadcastReceiver在10秒内没有执行完毕,Android会认为该程序无响应,所以在 BroadcastReceiver里不能做一些比较耗时的操作,否则会弹出ANR(Application No Response)的对话框。

ContentProvider

定义

  • 主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全

相关问题

  • 谈谈你对ContentProvider的理解
    同上
  • 说说ContentProvider、ContentResolver、ContentObserver 之间的关系
    在这里插入图片描述

Service

定义

  • 服务是一个后台运行的组件,执行长时间运行且不需要用户交互的任务。

启动和停止服务

  • 第一种:startService()/stopService()
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
  • 第二种: bindService()/unbindService()
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

Activity 与 Service 之间的通信

  • 通过Binder对象实现
    在Service中,创建Binder对象,重写onBind方法,将自定义的Binder返回。
    在这里插入图片描述
    在Activity中,通过监听Service的绑定和解除绑定,在绑定中获取binder,向下转型为我们自定义的binder,便可以进行更多的操作service的行为了
    在这里插入图片描述
    在这里插入图片描述

Service的生命周期

onCreate() - onStartCommand() - onDestory()

注意:如果同时调用 bindService() 和 startServicee() 需要调用 unBindService()和 stopService/stopSelf()才可以将服务销毁,即onDestory()才会被调用。

IntentService

  • 由于服务是在主线程中创建的,如果在服务中创建一些耗时操作,则会造成ANR。所以,创建服务后,需要在具体的子方法中,开启一个子线程,去处理耗时操作,操作完成后,才能停止服务。这一系列操作包含两点:①,需要创建子线程 ② 不能在外部控制停止服务的时间。所以引入IntentService解决这两个问题。 onHandleIntent()则自动在子线程中运行。
    在这里插入图片描述

相关问题:

  • Service与Activity的几种通信方式:
    1.通过Binder进行通信。可看如上的Binder实例。
    2.通过Service进行通信。
    详细讲解
  • 如何保证一个后台服务不被杀死?
    1.用 sticky 粘性的 servcie:Service 设置成 START_STICKY kill后会被重启(等待 5 秒左右),重传 Intent,保持与重启前一样
    2.多媒体锁:锁屏后循环播放无声音乐,解释后停止播放,实测在华为能永久保活,我们项目中就有用到。
    3.在 onDestroy 中再次启动:service +broadcast 方式,就是当service 走 ondestory 的时候,发送一个自定义的广播,当收到广播的时候,重新启动 service;
    4.提高进程优先级,将其设置为前台状态:通过 startForeground将进程设置为前台进程,做前台服务,优先级和前台应用一个级别 ,除非在系统内存非常缺,否则此进程不会被 kill
    Android 进程保活之—— startForeground保活
    5.用广播保持监听:注册高频率广播接收器,唤起进程。如网络变化,解锁屏幕,开机等
    6. 一像素存活: 在应用退到后台后,另起一个只有 1 像素的页面停留在桌面上,让自己保持前台状态,保护自己不被后台清理工具杀死
    一像素存活//但这种方法可能不是很可行。
    7.双进程 Service: 让 2 个进程互相保护,其中一个 Service 被清理后,另外没被清理的进程可以立即重启进程

代码详解:

ServiceOne.java

package com.example.servicedemo;
 
import java.util.Timer;
import java.util.TimerTask;
 
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
 
public class ServiceOne extends Service {
    
    public final static String TAG = "com.example.servicedemo.ServiceOne";
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand");
        
        thread.start();
        return START_STICKY;
    }
    
    Thread thread = new Thread(new Runnable() {
        
        @Override
        public void run() {
            Timer timer = new Timer();
            TimerTask task = new TimerTask() {
                
                @Override
                public void run() {
                    Log.e(TAG, "ServiceOne Run: "+System.currentTimeMillis());
                    boolean b = MainActivity.isServiceWorked(ServiceOne.this, "com.example.servicedemo.ServiceTwo");
                    if(!b) {
                        Intent service = new Intent(ServiceOne.this, ServiceTwo.class);
                        startService(service);
                        Log.e(TAG, "Start ServiceTwo");
                    }
                }
            };
            timer.schedule(task, 0, 1000);
        }
    });
 
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
 
}

ServiceTwo.java


package com.example.servicedemo;
 
import java.util.Timer;
import java.util.TimerTask;
 
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
 
public class ServiceTwo extends Service {
 
    public final static String TAG = "com.example.servicedemo.ServiceTwo";
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand");
 
        thread.start();
        return START_REDELIVER_INTENT;
    }
 
    Thread thread = new Thread(new Runnable() {
 
        @Override
        public void run() {
            Timer timer = new Timer();
            TimerTask task = new TimerTask() {
 
                @Override
                public void run() {
                    Log.e(TAG, "ServiceTwo Run: " + System.currentTimeMillis());
                    boolean b = MainActivity.isServiceWorked(ServiceTwo.this, "com.example.servicedemo.ServiceOne");
                    if(!b) {
                        Intent service = new Intent(ServiceTwo.this, ServiceOne.class);
                        startService(service);
                    }
                }
            };
            timer.schedule(task, 0, 1000);
        }
    });
 
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
 
}

Handler 、Message 、MessageQueue、 Looper
HandlerMessage MessageQueue Looper详细讲解

UI

常见的几种布局

线性布局 LinearLayout

  • 控件在线性方向进行排列。
  • 通过android:orientation 设置垂直和水平布局

帧布局 FrameLayout

  • 所用控件默认摆放在布局的左上角,相互覆盖。

相对布局 RelativeLayout

  • 控件相对父布局或相对其他控件进行排布。

约束布局 ContraintLayout

  • 新的一种布局方式,主要解决布局相互嵌套过多的问题,比如线性布局里放相对布局再放线性布局这样层层嵌套。
  • 可以独立设置每个控件的位置。

自定义控件

  • 自定义控件原理
  • 自定义View如何提供获取View属性的接口?

Recyclerview的使用方法

在这里插入图片描述

  • RecyclerView的基本使用
  • 过程
    ①创建RecyclerView布局
    ②创建Adapter 其中包括ViewHolder的创建,建立重用机制。
    ③创建LayoutManager设置横纵布局。

相关问题:
ListView 与 RecyclerView 的区别?
ListView 与 RecyclerView的区别

  • 布局效果: RecyclerView > ListView
    RecyclerView 可以实现横纵布局,但ListView 的布局单一,只可以实现纵向布局
  • 局部刷新 RecyclerView > ListView
    RecyclerView 可以自带方法实现局部刷新(包括删除、更新数据、添加数据),ListView也可以实现,但需要代码手动书写。
  • 动画效果 RecyclerView > ListView
    RecyclerView 自带ItemAnimatior的动画效果方法,但ListView却没有
  • 数据的头和尾的样式 ListView > RecyclerView
    ListView 可以自定义头尾item样式,但RecyclerView全部是统一的ItemView,需要自己手动代码更改。
  • 空数据处理 ListView > RecyclerView ListView
    自带列表数据判空的方法,RecyclerView需要自己根据列表数据进行判断。

:RecyclerView中 ,如果一个itemView设置点击监听事件,itemView中包含TextView和ImageView,ImageView设置了点击监听,TextView没有设置点击监听。
问题:
1.点击itemview中的TextView,如图点击①位置,谁会响应监听?
2.点击itemView,如图②位置,谁会响应监听?
3. 点击itemView中的ImageView,如图③位置,谁会响应监听?
4.itemView的监听是否会被ImageView的监听覆盖,或者ImageVIew的监听是否会被覆盖监听呢?

在这里插入图片描述
答:
1.2.点击①和②的位置,都是有itemView响应监听,因为①的位置没有设置监听,所以由父布局,itemView进行响应监听。
3.点击③的位置,由ImageVIew响应,因为子布局设置了监听事件,根据View的事件分发机制,如果子布局进行消费,则该事件已经被消费,停止点击事件的事件分发。所以,子布局ImageView的点击事件会优先被执行。
4.该点击事件不会再分发给父布局ItemVIew进行处理,此题考察的是View的事件分发机制,并不是覆盖不覆盖的问题。

Fragment

碎片是什么?

  • 碎片(Fragment)是一种可以嵌入在活动中的UI片段,它能让程序更加合理和充分的利用大屏幕的空间,因为在平板上应用的非常广泛。

生命周期:

在这里插入图片描述
相关问题

Activity与Fragment之间生命周期比较?
多了五种状态:
onAttach() 在Fragment 和 Activity 建立关联是调用(Activity 传递到此方法内)
onCreateView() 当Fragment 创建视图时调用
onActivityCreated() 在相关联的 Activity 的 onCreate() 方法已返回时调用。
onDestroyView() 当Fragment中的视图被移除时调用
onDetach() 当Fragment 和 Activity 取消关联时调用。

如何实现Fragment的滑动?
通过ViewPager + Fragment
Tablayout + ViewPager + Fragment

Fragment中,返回上一个Fragment 如何实现?正常情况下并不能返回到上一个Fragment中。
和Activity相同的思路是,添加到回退栈中,但不同点方式,是,通过
transaction.addToBackStack(null)的方式,在替换ReplaceFragment提交之前,调用这个方法。
在这里插入图片描述
fragment之间传递数据的方式?
① Fragment1 与 Fragment2 传递数据
方法一:情景:Fragment1 跳转到Fragment2 并携带数据
通过 setArguments(bundle数据) getArguments() 设置 可取出参数
Fragment 与 Fragment 之间传递数据
步骤:
①Fragment2中,新建 一个 返回值类型为Fragment2的newInstance(String data)方法 //此步骤也可忽略
②Bundle携带数据,fragment.setArguments(bundle数据) 放入数据
③在Fragment1 中,通过Fragment2.newInstance(添加需要传递数据)
④在Fragment2 的onCreateView中,通过getArguments()的方法获取数据。
代码解释:
这两个方法都在Fragment2中,newInstance()是在Fragment1中需要传递数据的时候调用的。onCreateView是Fragment2的生命周期。
在这里插入图片描述
在这里插入图片描述
方法二:情景:Fragment1 与Fragment2在同一个Activity中,并且只静态使用。直接通过findViewById找到两个Fragment中的任意控件,进行赋值即可。
② Fragment 与Activity之间传递数据。
Fragment 可以通过getActivity().get可以随意获取到宿主Activity的数据。
Activity 可以通过接口回调的方式获取Fragment中的数据
接口回到的方式

Fragment的动态使用和静态使用?
动态,就是动态添加和替换。
静态,则是将<xxx.com.Fragment></xxx.com.Fragment>写到布局文件中。
更加详细的Fragment讲解

高级技巧

  • 创建定时服务:
    在这里插入图片描述

  • 序列化对象之Serializable
    在这里插入图片描述
    在这里插入图片描述

  • 序列化对象之Parcelable
    在这里插入图片描述
    Serializable 与 Parcelable 比较:Serializable使用简单,但会将整个对象进行序列化,效率较低,通常推荐使用Parcelable的方式传递Intent对象。

  • DOZE模式
    当用户的设备是Android 6.0以上或以上的系统时,如果该设备未插接电源,处于静止状态,且屏幕关闭了一段时间后,就会进入DOZE模式。

  • Android 版本型号与targetSdkVersion的匹配:

  • 设置Activity在以下的几种情况下不会重新创建
    在这里插入图片描述

  • 获取Activity当前状态发生变化回调
    重写Activity中的onConfigurationChange()

  • 禁止程序的被切换成多窗口
    在这里插入图片描述

  • 允许应用多语言设置的时候可以从右到左编排布局

    android:supportsRtl="false"
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值