Android笔记

Android笔记

前言: 本笔记基于MacOS系统

学习意图: 为了做逆向打基础

笔记内容: android的重要组件和功能(不死扣细节)

学习目标: 拿到一套android代码可以通过读代码方式可以理清自己需要的部分功能的实现逻辑.

附加目标: 当需要写android时,可以根据自己的需要快速定位开发

软件(flutter、dart和vscode可以不装)

jdk + flutter + android studio + dart+ vscode(机子性能好可以选android studio + android SDK + jdk)

安装

1、jdk 12

mac自带,建议自己配置一个java8,新版本总会有各种不兼容

2、flutter sdk(如果不想写原生android的话)

2.1 下载

地址:https://flutter.dev/docs/get-started/install

解压到指定目录: 如 ~

2.2 环境配置

官方教程: https://flutter.dev/docs/get-started/install/macos

在~/.zshrc(或者.bashrc、.bash_profile) 中最后一行添加

export PATH="$PATH:~/flutter/bin"

重新source ~/.zshrc

3、vscode(机子性能不足,用vscode写)

https://vscode.cdn.azure.cn/stable/26076a4de974ead31f97692a0d32f90d735645c0/VSCode-darwin-stable.zip

下载完毕后,安装flutter和dart

dart安装、配置

brew install dart
vim ~/.zshrc
# 最后两行添加,其中DART_HOME为dart的安装路径
export DART_HOME=/usr/local/Cellar/dart/2.8.0-dev.0.0/bin
export PATH="${DART_HOME}:${PATH}"

4、AS(android studio)

4.1 下载

android studio下载

http://down-ww3.newasp.net/pcdown/big/android_studio_ide_mac.dmg

下载完毕后,直接安装,遇到设置代理会报红,取消即可.后面就是next -> next…

创建项目,项目命名规则为驼峰式,next…创建完一般情况下会报错,暂时不管,到AS配置步骤解决

Android sdk下载

https://dl.google.com/android/repository/tools_r25.2.3-macosx.zip

# 解压后,进入tools目录
cd tools
.android sdk

勾选Extras,然后下载.

gradle配置

cd ~
vim .zshrc(或者.bashrc)
# 在最后添加
# 配置gradle环境,GRADLE_HOME路径为AS路径下gradle下的gradle
export GRADLE_HOME=/Applications/Android\ Studio.app/Contents/gradle/gradle-4.4
export PATH=${PATH}:${GRADLE_HOME}/bin
# 退出保存 :wq
# 然后测试
gradle -version

------------------------------------------------------------
Gradle 4.4
------------------------------------------------------------

Build time:   2017-12-06 09:05:06 UTC
Revision:     cf7821a6f79f8e2a598df21780e3ff7ce8db2b82

Groovy:       2.4.12
Ant:          Apache Ant(TM) version 1.9.9 compiled on February 2 2017
JVM:          1.8.0_231 (Oracle Corporation 25.231-b11)
OS:           Mac OS X 10.14.4 x86_64

AS配置

1、打开文件目录下Gradle Scripts -> build.gradle

全选修改(设置国内镜像源)

buildscript {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven{ url 'https://maven.aliyun.com/repository/jcenter'}
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.0'
    }
}

allprojects {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven{ url 'https://maven.aliyun.com/repository/jcenter'}
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

2、打开文件目录下Gradle Scripts -> gradle-wrapper.propertiies

#Thu Jan 02 10:38:22 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip

3、File -> Project structure

勾选 Idk location下的Use embezzlementdded JDK

4、Preferences -> Build,Execution,Deployment -> Gradle -> Android Studi

勾选Enable embedded Maven repository

5、Try again

6、创建虚拟设备(可以直接连接手机)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

7、运行第一个程序
在这里插入图片描述
在这里插入图片描述

笔记指南

一个完整的安卓系统大致上由一个界面使用各种布局方式承载各种组件,并且在组件上绑定各种事件,通过与用户与组件的交互,激活与事件绑定的后台逻辑,然后反馈给用户,实现一个app的各种功能.

四大应用组件

  • Activity
  • 服务
  • 广播接收器
  • 内容提供程序

Activity(界面)、服务(调度器,大管家)、广播接收器(全局消息)、内容提供器(数据库) (总结)

Activity

Activity 是与用户交互的入口点。它表示拥有界面的单个屏幕。例如,电子邮件应用可能有一个显示新电子邮件列表的 Activity、一个用于撰写电子邮件的 Activity 以及一个用于阅读电子邮件的 Activity。尽管这些 Activity 通过协作在电子邮件应用中形成一种紧密结合的用户体验,但每个 Activity 都独立于其他 Activity 而存在。因此,其他应用可以启动其中任何一个 Activity(如果电子邮件应用允许)。例如,相机应用可以启动电子邮件应用内用于撰写新电子邮件的 Activity,以便用户共享图片。Activity 有助于完成系统和应用程序之间的以下重要交互:
		追踪用户当前关心的内容(屏幕上显示的内容),以确保系统继续运行托管Activity 的进程。
		了解先前使用的进程包含用户可能返回的内容(已停止的 Activity),从而更优先保留这些进程。
		帮助应用处理终止其进程的情况,以便用户可以返回已恢复其先前状态的 Activity。
	提供一种途径,让应用实现彼此之间的用户流,并让系统协调这些用户流。(此处最经典的示例是共享。)

服务

服务是一个通用入口点,用于因各种原因使应用在后台保持运行状态。它是一种在后台运行的组件,用于执行长时间运行的操作或为远程进程执行作业。服务不提供界面。例如,当用户使用其他应用时,服务可能会在后台播放音乐或通过网络获取数据,但这不会阻断用户与 Activity 的交互。诸如 Activity 等其他组件可以启动服务,使该服务运行或绑定到该服务,以便与其进行交互。事实上,有两种截然不同的语义服务可以告知系统如何管理应用:已启动服务会告知系统使其运行至工作完毕。此类工作可以是在后台同步一些数据,或者在用户离开应用后继续播放音乐。在后台同步数据或播放音乐也代表了两种不同类型的已启动服务,而这些服务可以修改系统处理它们的方式:
		音乐播放是用户可直接感知的服务,因此,应用会向用户发送通知,表明其希望成为前台,从而告诉系统此消息;在此情况下,系统明白它应尽全力维持该服务进程运行,因为进程消失会令用户感到不快。
		通常,用户不会意识到常规后台服务正处于运行状态,因此系统可以更自由地管理其进程。如果系统需要使用 RAM 来处理用户更迫切关注的内容,则其可能允许终止服务(然后在稍后的某个时刻重启服务)。
绑定服务之所以能运行,原因是某些其他应用(或系统)已表示希望使用该服务。从根本上讲,这是为另一个进程提供 API 的服务。因此,系统会知晓这些进程之间存在依赖关系,所以如果进程 A 绑定到进程 B 中的服务,系统便知道自己需使进程 B(及其服务)为进程 A 保持运行状态。此外,如果进程 A 是用户关心的内容,系统随即也知道将进程 B 视为用户关心的内容。由于存在灵活性(无论好坏),服务已成为非常有用的构建块,并且可实现各种高级系统概念。动态壁纸、通知侦听器、屏幕保护程序、输入方法、无障碍功能服务以及众多其他核心系统功能均可构建为在其运行时由应用实现、系统绑定的服务。

广播接收器

借助广播接收器组件,系统能够在常规用户流之外向应用传递事件,从而允许应用响应系统范围内的广播通知。由于广播接收器是另一个明确定义的应用入口,因此系统甚至可以向当前未运行的应用传递广播。例如,应用可通过调度提醒来发布通知,以告知用户即将发生的事件。而且,通过将该提醒传递给应用的广播接收器,应用在提醒响起之前即无需继续运行。许多广播均由系统发起,例如,通知屏幕已关闭、电池电量不足或已拍摄照片的广播。应用也可发起广播,例如,通知其他应用某些数据已下载至设备,并且可供其使用。尽管广播接收器不会显示界面,但其可以创建状态栏通知,在发生广播事件时提醒用户。但广播接收器更常见的用途只是作为通向其他组件的通道,旨在执行极少量的工作。例如,它可能会根据带 JobScheduler 的事件调度 JobService 来执行某项工作

广播接收器作为 BroadcastReceiver 的子类实现,并且每条广播都作为 Intent 对象进行传递。如需了解详细信息,请参阅 BroadcastReceiver 类。

内容提供程序

内容提供程序管理一组共享的应用数据,您可以将这些数据存储在文件系统、SQLite 数据库、网络中或者您的应用可访问的任何其他持久化存储位置。其他应用可通过内容提供程序查询或修改数据(如果内容提供程序允许)。例如,Android 系统可提供管理用户联系人信息的内容提供程序。因此,任何拥有适当权限的应用均可查询内容提供程序(如 ContactsContract.Data),以读取和写入特定人员的相关信息。我们很容易将内容提供程序看作数据库上的抽象,因为其内置的大量 API 和支持时常适用于这一情况。但从系统设计的角度看,二者的核心目的不同。对系统而言,内容提供程序是应用的入口点,用于发布由 URI 架构识别的已命名数据项。因此,应用可以决定如何将其包含的数据映射到 URI 命名空间,进而将这些 URI 分发给其他实体。反之,这些实体也可使用分发的 URI 来访问数据。在管理应用的过程中,系统可以执行以下特殊操作:
		分配 URI 无需应用保持运行状态,因此 URI 可在其所属的应用退出后继续保留。当系统必须从相应的 URI 检索应用数据时,系统只需确保所属应用仍处于运行状态。
		这些 URI 还会提供重要的细粒度安全模型。例如,应用可将其所拥有图像的 URI 放到剪贴板上,但将其内容提供程序锁定,以便其他应用程序无法随意访问它。当第二个应用尝试访问剪贴板上的 URI 时,系统可允许该应用通过临时的 URI 授权来访问数据,这样便只能访问 URI 后面的数据,而非第二个应用中的其他任何内容。
内容提供程序也适用于读取和写入您的应用不共享的私有数据。

声明组件

  • Activity — 元素
  • 服务 — 元素
  • 广播接收器 — 元素
  • 内容提供程序 — 元素

布局

  • LinearLayout
  • RelativeLayout
  • TableLayout
  • FrameLayout
  • AbsoluteLayout(待删除,不建议使用)
  • GridLyout

布局就是按照设计图选择最合适的排版模板(总结)

LinearLayout

线性布局是Android中较为常用的布局方式,使用LinearLayout标签。线性布局主要有两种形式,一种是水平线性布局,一种是垂直线性布局。需要注意的是Android的线性布局不会换行,当组件一个挨着一个地排列到头之后,剩下的组件将不会被显示出来。

RelativeLayout

相对布局,使用RelativeLayout标签。相对布局通常有两种形式,一种是相对于容器而言的,一种是相对于控件而言的。

TableLayout

表格布局就是让控件以表格的形式来排列控件,只要将控件放在单元格中,控件就可以整齐地排列,使用TableLayout标签。

TableLayout继承了 LinearLayout,因此它的本质依然是线性布局管理器。每次向TableLayout中添加一个TableRow,该TableRow就是一个表格行,TableRow也是容器,因此它也可以不断地添加其他组件,每添加一个子组件该表格就增加一列。如果直接向TableLayout中添加组件,那么这个组件将直接占用一行。

在表格布局中,列的宽度由该列中最宽的那个单元格决定,整个表格布局的宽度则取决于父容器的宽度(默认总是占满父容器本身)。

FrameLayout

帧布局为每个加入其中的控件创建一个空白区域(称为一帧,每个控件占据一 帧)。釆用帧布局方式设计界面时,只能在屏幕左上角显示一个控件,如果添加多个控件,这些控件会按照顺序在屏幕的左上角重叠显示。

AbsoluteLayout(待删除,不建议使用)

绝对布局需要通过指定x、y坐标来控制每一个控件的位置,放入该布局的控件需要通过android:layout_x和android:layout_y 两个属性指定其准确的坐标值,并显示在屏幕上。

需要注意的是当使用AbsoluteLayout作为布局容器时,布局容器不再管理子组件的位置和大小,都需要开发人员自己控制。使用绝对布局时,每个子组件都可指定如下两个XML属性。

GridLyout

网格布局实现了控件的交错显示,能够避免因布局嵌套对设备性能的影响,更利于自由布局的开发。网格布局用一组无限细的直线将绘图区域分成行、列和单元,并指定控件的显示区域和控件在该区域的显示方式

View

部分组件

  • TextView
  • EditText
  • Button
  • CheckBox
  • RadioBox
  • Boggle
  • Switch
  • ImageView
  • ImageButton
  • ZoomButton

View实际上就是界面展示的各种组件,组件配合布局构成了用户展示界面(总结)

Android 应用的界面 (UI) 以布局和微件的层次结构形式构建而成。布局是 ViewGroup 对象,即控制其子视图在屏幕上的放置方式的容器。微件是 View 对象,即按钮和文本框等界面组件。

ViewGroup
ViewGroup
View
View
View
View

TextView

  • 功能: 在界面上显示文本

  • 父类: View

  • 子类: EditText、Button

EditText

  • 功能: 接收用户输入
  • 父类: TextView

Button

  • 功能: 绑定点击事件,实现某些逻辑
  • 父类: TextView

CheckBox

  • 功能: 多选

RadioBox

  • 功能: 单选

Boggle

  • 功能: 选中

Switch

  • 功能: 切换

ImageView

  • 功能: 展示图片

ImageButton

  • 功能: 带有图片的按钮

ZoomButton

  • 放大缩晓

事件 (重要)

Android事件处理方式分两种方式:

  • 基于监听的事件处理
  • 基于回调的事件处理

**触发事件后,事件传播流程,用户界面的各个View(组件)配合事件构成app的各种功能(总结): **

注意事项
触发事件
返回true
返回true
返回false
返回false
事件监听器
事件监听处理
事件回调处理
结束
结束
事件源

1、基于监听的事件处理

Event Source (事件源):事件发生的场所,通常就是各个组件,例如按钮、窗口、菜单等。

Event (事件):事件封装了界面组件上发生的特定事情(通常就是一次用户操作)。如果程序需要获得界面组件上所发生事件的相关信息,一般通过Event对象来取得。

Event Listener (事件监听器):负责监听事件源所发生的事件,并对各种事件做出相应的响应。

当用户按下一个按钮或者单击某个菜单项时,这些动作就会激发一个相应的事件,该事件就会触发事件源上注册的事件监听器(特殊的Java对象),事件监听器调用对应的事件处理器 (事件监听器里的实例方法)来做出相应的响应。

每个组件均可以针对特定的事件指定一个事件监听器,每个事件监听器也可监听一个或多个事件源。因为同一个事件源上可能发生多种事件,委派式事件处理方式可以把事件源上所有可能发生的事件分别授权给不同的事件监听器来处理;同时也可以让一类事件都使用同一个事件监听器来处理。

在基于监听的事件处理模型中,事件监听器必须实现事件监听器接口,Android为不同的界面组件提供了不同的监听器接口,这些接口通常以内部类的形式存在。以View类为例,它包含了如下几个内部接口。

View.OnClickListener:单击事件的事件监听器必须实现的接口。

View.OnCreateContextMenu Listener :创建上下文菜单事件的事件监听器必须实现的接口。

View.onFocusChangeListener:焦点改变事件的事件监听器必须实现的接口。

View.OnKeyListener:按键事件的事件监听器必须实现的接口。

View.OnLongClickListener:长按事件的事件监听器必须实现的接口。

View.OnTouchListener:触摸事件的事件监听器必须实现的接口。

实现形式:

  • 使用匿名内部类作为事件监听器
  • 使用内部类作为事件监听器
  • 使用外部类作为事件监听器
  • 直接使用Activity作为事件监听器
  • 直接绑定到标签

实例:

layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="用户名: "
        android:textSize="16sp" />

    <EditText
        android:id="@+id/name_et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入用户名"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="密码: "
        android:textSize="16sp"/>

    <EditText
        android:id="@+id/pwd_et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入密码"/>

    <Button
        android:id="@+id/login_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="普通按钮"/>

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    EditText mNameEt = null;
    EditText mPasswordEt = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout);
        // 获取界面组件
        mNameEt = findViewById(R.id.name_et);
        mPasswordEt = findViewById(R.id.pwd_et);
        Button btnClick =  findViewById(R.id.login_btn);
        btnClick.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view){
                String name = mNameEt.getText().toString();
                String password = mPasswordEt.getText().toString();
                Toast.makeText(MainActivity.this, "按钮被点击" + name + password,
                        Toast.LENGTH_SHORT).show();
            }
        });
    }

2、基于回调的事件处理

对于基于回调的事件处理模型来说,事件源与事件监听器是统一的,或者说事件监听器完全消失了。当用户在GUI组件上激发某个事件时,组件自己特定的方法将会负责处理该事件。

为了实现回调机制的事件处理,Android为所有GUI组件都提供了一些事件处理的回调方法,以View为例,该类包含如下方法。

boolean onKeyDown(int keyCode, KeyEvent event):当用户在该组件上按下某个按键时触发该方法。

boolean onKeyLongPress(int keyCode, KeyEvent event):当用户在该组件上长按某个按键时触发该方法。

boolean onKeyShortcut(int keyCode, KeyEvent event):当一个键盘快捷键事件发生时触发该方法。

boolean onKeyUp(int keyCode, KeyEvent event):当用户在该组件上松开某个按键时触发该方法。

boolean onTouchEvent(MotionEvent event):当用户在该组件上触发触摸屏事件时触发该方法。

boolean onTrackballEvent(MotionEvent event):当用户在该组件上触发轨迹球事件时触发该方法。

void onFocusChanged(boolean gainFocus, int direction, Rect previously FocusedRect):当组件的焦点发生改变时触发该方法。和前面的6个方法不同,该方法只能够在View中重写。

Android系统事件响应

对Android系统事件的响应处理,实际上时对Configuration类的处理,系统事件响应主要解决app共享系统资源问题(总结)

在开发Android应用时,有时候可能需要让应用程序随系统设置而进行调整,比如判断系统的屏幕方向、判断系统方向的方向导航设备等。除此之外,有时候可能还需要让应用程序监听系统设置的更改,对系统设置的更改做出响应.

Configuration类专门用于描述手机设备上的配置信息,这些配置信息既包括用户特定的配置项,也包括系统的动态设备配置。程序可调用Activity的如下方法来获取系统的Configuration对象:

Configurationcfg=getResources().getConfiguration();

一旦获得了系统的Configuration对象,就可以使用该对象提供的如下常用属性来获取系统的配置信息。

常用的配置常量

densityDpi:屏幕密度。

fontScale:当前用户设置的字体的缩放因子。

hardKeyboardHidden:判断硬键盘是否可见,有两个可选值:

      HARDKEYBOARDHIDDEN_NO,值为十六进制的0。

      HARDKEYBOARDHIDDEN_YES,值为十六进制的1。

keyboard:获取当前关联额键盘类型:该属性的返回值:

      KEYBOARD_12KEY:只有12个键的小键盘。

      KEYBOARD_NOKEYS:无键盘。

      KEYBOARD_QWERTY:普通键盘。

keyboardHidden:该属性返回一个boolean值用于标识当前键盘是否可用。该属性不仅会判断系统的硬件键盘,也会判断系统的软键盘(位于屏幕)。

locale:获取用户当前的语言环境。

mcc:获取移动信号的国家码。

mnc:获取移动信号的网络码。

ps:国家代码和网络代码共同确定当前手机网络运营商。

navigation:判断系统上方向导航设备的类型。该属性的返回值:

      NAVIGATION_NONAV:无导航。

      NAVIGATION_DPAD:DPAD导航。

      NAVIGATION_TRACKBALL:轨迹球导航。

      NAVIGATION_WHEEL:滚轮导航。

orientation:获取系统屏幕的方向。该属性的返回值:

      ORIENTATION_LANDSCAPE:横向屏幕。

      ORIENTATION_PORTRAIT:竖向屏幕。

screenHeightDp,screenWidthDp:屏幕可用高和宽,用dp表示。

touchscreen:获取系统触摸屏的触摸方式。该属性的返回值:

      TOUCHSCREEN_NOTOUCH:无触摸屏。

      TOUCHSCREEN_STYLUS:触摸笔式触摸屏。

      TOUCHSCREEN_FINGER:接收手指的触摸屏。

如果程序需要监听系统设置的更改,则可以考虑重写Activity的onConfigurationChanged (Configuration newConfig)方法,该方法是一个基于回调的事件处理方法:当系统设置发生更改时,该方法会被自动触发。

当然,为了让Activity能监听系统配置更改的事件,需要在配置Activity时指定 androidiconfigChanges 属性,该属性可以支持 mcc、mnc、locale、touchscreen、keyboard、keyboardHidden、navigation、orientation、screenLayout、uiMode、screenSize、smallestScreenSize、fontScale等属性值。

Activity

Activity是Android组件中最基本也是最常用的一种组件,在一个Android应用中,一个Activity通常就是一个单独的屏幕。每一个Activity都被实现为一个独立的类,并且继承于Activity这个基类。

Activity生命周期
在这里插入图片描述

实例:

链接:https://pan.baidu.com/s/1FB12ZvqlAB0TE4PAw-fxPg 密码:pq07

Task

Android中对于Activity的管理采用Task的概念,在应用程序中每个被创建的Activity都保存在回退堆栈内,每次后退就将栈顶的Activity取出.

Service

Service是Android提供一个允许长时间留驻后台的一个组件,最常见的 用法就是做轮询操作,同时,Service提供跨进程通信组件!

Service生命周期

在这里插入图片描述

StartService启动Service

首次启动会创建一个Service实例,依次调用onCreate()和onStartCommand()方法,此时Service 进入运行状态,如果再次调用StartService启动Service,将不会再创建新的Service对象, 系统会直接复用前面创建的Service对象,调用它的onStartCommand()方法!
但这样的Service与它的调用者无必然的联系,就是说当调用者结束了自己的生命周期, 但是只要不调用stopService,那么Service还是会继续运行的!
无论启动了多少次Service,只需调用一次StopService即可停掉Service

BindService启动Service

当首次使用bindService绑定一个Service时,系统会实例化一个Service实例,并调用其onCreate()和onBind()方法,然后调用者就可以通过IBinder和Service进行交互了,此后如果再次使用bindService绑定Service,系统不会创建新的Sevice实例,也不会再调用onBind()方法,只会直接把IBinder对象传递给其他后来增加的客户端!
如果我们解除与服务的绑定,只需调用unbindService(),此时onUnbind和onDestory方法将会被调用!这是一个客户端的情况,假如是多个客户端绑定同一个Service的话,情况如下 当一个客户完成和service之间的互动后,它调用 unbindService() 方法来解除绑定。当所有的客户端都和service解除绑定后,系统会销毁service。(除非service也被startService()方法开启)
另外,和上面那张情况不同,bindService模式下的Service是与调用者相互关联的,可以理解为 “一条绳子上的蚂蚱”,要死一起死,在bindService后,一旦调用者销毁,那么Service也立即终止!
通过BindService调用Service时调用的Context的bindService的解析 bindService(Intent Service,ServiceConnection conn,int flags)
service:通过该intent指定要启动的Service
conn:ServiceConnection对象,用户监听访问者与Service间的连接情况, 连接成功回调该对象中的onServiceConnected(ComponentName,IBinder)方法; 如果Service所在的宿主由于异常终止或者其他原因终止,导致Service与访问者间断开 连接时调用onServiceDisconnected(CompanentName)方法,主动通过unBindService() 方法断开并不会调用上述方法!
flags:指定绑定时是否自动创建Service(如果Service还未创建), 参数可以是0(不自动创建),BIND_AUTO_CREATE(自动创建)

StartService启动Service后bindService绑定

如果Service已经由某个客户端通过StartService()启动,接下来由其他客户端 再调用bindService()绑定到该Service后调用unbindService()解除绑定最后在 调用bindService()绑定到Service的话,此时所触发的生命周期方法如下:
onCreate( )->onStartCommand( )->onBind( )->onUnbind( )->onRebind( )
**PS:**前提是:onUnbind()方法返回true!!! 这里或许部分读者有疑惑了,调用了unbindService后Service不是应该调用 onDistory()方法么!其实这是因为这个Service是由我们的StartService来启动的 ,所以你调用onUnbind()方法取消绑定,Service也是不会终止的!
得出的结论: 假如我们使用bindService来绑定一个启动的Service,注意是已经启动的Service!!! 系统只是将Service的内部IBinder对象传递给Activity,并不会将Service的生命周期 与Activity绑定,因此调用unBindService( )方法取消绑定时,Service也不会被销毁!

IntentService

IntentService是继承与Service并处理异步请求的一个类,在IntentService中有 一个工作线程来处理耗时操作,请求的Intent记录会加入队列

当需要有耗时的操作,就放在后台进行,此时需要使用IntentService(总结)

客户端通过startService(Intent)来启动IntentService; 我们并不需要手动地区控制IntentService,当任务执行完后,IntentService会自动停止; 可以启动IntentService多次,每个耗时操作会以工作队列的方式在IntentService的 onHandleIntent回调方法中执行,并且每次只会执行一个工作线程,执行完一,再到二这样!

Binder

Binder用来实现Android跨进程通信的一种机制,也是Android程序中的一个类.

Binder流程:
在这里插入图片描述

BroadcastReceiver

广播,相当于一个全局的事件监听器和消息发送器.

ContentProvider

在这里插入图片描述

自定义ContentProvider
在这里插入图片描述

通过ContentObserver监听ContentProvider的数据变化

在这里插入图片描述

Intent

1.显式Intent与隐式Intent的区别

  • 显式Intent:通过组件名指定启动的目标组件,比如startActivity(new Intent(A.this,B.class)); 每次启动的组件只有一个~
  • 隐式显式Intent:不指定组件名,而指定Intent的Action,Data,或Category,当我们启动组件时, 会去匹配AndroidManifest.xml相关组件的Intent-filter,逐一匹配出满足属性的组件,当不止一个满足时, 会弹出一个让我们选择启动哪个的对话框~

2.Intent的七个属性

  1. ComponentName
    在这里插入图片描述

2)Action
在这里插入图片描述

3)Category
在这里插入图片描述

  1. Data,Type
    在这里插入图片描述

5)Extras
在这里插入图片描述

6)Flags
在这里插入图片描述

3 隐式Intent
在这里插入图片描述

数据读写

文件操作模式
在这里插入图片描述

SharedPreferences保存用户偏好参数
在这里插入图片描述

笔记来源: w3cschool、简书、CSDN

发布了66 篇原创文章 · 获赞 23 · 访问量 6万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览