第一行代码 Android读书笔记

  • 第一章 开始启程-你的第一行Android代码
    • Android系统架构
    • Android应用开发特色
    • 搭建开发环境
    • 创建第一个Android项目
    • 运行第一个Android项目
    • 分析第一个Android项目
    • 掌握日志工具的使用
  • 第二章 先从看得到的入手-探究活动
    • 活动是什么
    • 手动创建活动
    • 创建和加载布局
    • 注册活动以及配置主活动
    • 在活动中使用Toast
    • 在活动中使用Menu
    • 销毁活动
    • 使用Intent在活动之间穿梭
    • 更多隐式Intent的用法
    • 向活动传递数据
    • 活动的生命周期
    • 活动被回收了怎么办
    • 活动的启动模式
    • 活动的最佳实践

第一章 开始启程-你的第一行Android代码

Android系统架构

Android大致可以分为四层架构:Linux内核层、系统运行库层、应用框架层、应用层。
1. Linux内核层
Android系统是基于Linux内核的,这一层为Android设备的各种硬件提供了底层的驱动,如显示驱动、音频驱动、照相机驱动、蓝牙驱动、Wi-Fi驱动、电源管理。
2. 系统运行库层
这一层通过一些c/c++库来为Android系统提供了主要的特性支持。如SQLite库提供了数据库的支持,OpenGL|ES提供了3D绘图的支持,Webkit提供了浏览器内核的支持。
在这一层还有Android运行时库,他主要提供了一些核心库,能够允许开发这使用Java语言来编写Android应用。另外,Android运行时库中还包含了Dalvik虚拟机(5.0系统之后改为ART运行环境),它使得每一个Android应用都能运行在独立的进程当中,并且拥有一个自己的Dalvik虚拟机实例。相较于Java虚拟机,Dalvik是专门为移动设备定制的。它针对手机内存、CPU性能有限等情况做了优化处理。
3. 应用框架层
这一层主要提供了构建应用程序时可能用到的各种API,Android自带的一些核心应用就是使用这些API完成,开发者也可以通过这些API来构建自己的应用程序
4. 应用层
所有安装在手机上的应用程序都是属于这一层的。

Android应用开发特色

1. 四大组件
Android系统四大组件分别是活动(Activity)、服务(Service)、广播接收器(Broadcast Receiver)和内容提供器(Content Provider)。其中活动是所有Android应用程序的门面,凡是在应用中你看得到的东西,都是放在活动中的。而服务就比较低调了,你无法看到它,但它会一直在后台默默地运行,即使用户退出了应用,服务仍然是可以继续运行的。广播接收器允许你的应用接收来自各处的广播消息,比如电话,短信等。当然你的应用也可以向外发出广播消息。内容提供器则为应用程序之间共享数据了可能,比如你想要读取系统电话本中的联系人,就需要通过内容提供器来实现。
2. 丰富的系统控件
Android系统为开发者提供了丰富的系统控件,使得我们可以很轻松地编写出漂亮的界面。也可以自己定制自己的控件。
3.SQLite数据库
Android系统还自带了这种轻量级、运算速度极快的嵌入式关系型数据库,不仅支持标准的SQL语法,还可以通过Android封装好的API进行操作、让存储和读取数据变得非常方便。
4. 强大的多媒体
Android系统还提供了丰富的多媒体服务,如音乐、视频、录音、拍照等等。这些都可以在程序中通过代码进行控制。
5. 地理位置定位
Android手机都内置GPS。

搭建开发环境

  1. 下载JDKJDK官网下载链接
  2. 下载IDEAIDEA下载链接
  3. 下载Android SDK,通过idea下载
    打开idea,新建一个项目,选择android,点击install SDK进行下载。第一行代码 Android读书笔记(一)_第1张图片

创建第一个Android项目

第一行代码 Android读书笔记(一)_第2张图片* name为软件名称,package name是项目的包名,Andriod系统是通过包名来区分不同的应用程序,所以要保证包名的唯一性。Minimum API Level为项目的最低兼容版本*
第一行代码 Android读书笔记(一)_第3张图片

运行第一个Android项目

1.点击菜单栏File下的project structure。配置Artifacts。artifact是一种用于装载项目资产以便于测试,部署,或者分布式软件的解决方案。
第一行代码 Android读书笔记(一)_第4张图片2. 选择运行设备
第一行代码 Android读书笔记(一)_第5张图片

分析第一个Android项目

1. 项目结构的分析
第一行代码 Android读书笔记(一)_第6张图片
4. .gradle和.idea都是自动生成的一些文件,无需关心,也不需要编辑。
5. app :项目中的代码、资源等内容几乎都是放置在这个目录下的。
6. gradle:这个目录下包含了gradle wrapper的配置文件,使用gradle wrapper的方式不需要将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle。
7. .gitgnore:这个文件是用来将指定的目录或文件排除在版本控制之外的。
8. build.gradle:项目全局的gradle构建脚本,通常这个文件的内容是不需要修改的。
9. gradle.properties:全局的gradle配置文件,在这里配置的属性将会影响到项目中所有的gradle编译脚本。
10. gradlew和gradlew.bat:用来是命令行界面执行gradle命令,其中gradlew是在linux或mac系统中使用的,gradlew.bat是在windows系统中使用的。
11. 项目名.iml:自动生成的文件,用于标识这是一个IntelliJ IDEA项目,不需要修改这个文件中的任何内容。
12. local.properties:用于指定本机中的Android SDK路径,通常内容都是自动生成的,不需要修改。
10.settings.gradle:这个文件用于指定项目中所有引入的模块。
2. app目录的分析
第一行代码 Android读书笔记(一)_第7张图片
1 build:主要包含了一些在编译时自动生成的文件,不需要过多关心。
2 libs:在项目中使用的第三方jar包,放在这个目录下的jar包会自动添加到构建路径里去。
3 androidTest:用来编写Android Test测试用例,可以对项目进行一些自动化测试。
4 main下面的java:放置所有Java代码的地方。
5 res:项目中使用到的所有图片、布局、字符串等资源需要存放在这个目录下。图片放在drawable目录下,布局放在layout目录下,字符串放在values目录下。应用图标放在mipmap目录下。
6 AndroidMainifest.xml:整个Android项目的配置文件,在程序中定义的所有四大组件都需要在这个文件里注册,还可以在这个文件中给应用程序添加权限声明。
7 test:用来编写Unit Test测试用例的,是对项目进行自动化测试的另一种方式。
8 gitinore:这个文件用于将app模块内的指定的目录或文件排除在版本控制之外。
9 app.iml:自动生成的文件,不需要关心。
10 build.gradle:这是app模块的gradle构建脚本,这个文件中会指定很多项目构建相关的配置。
11 proguard-rules.pro:这个文件用于指定项目代码的混淆规则,当代码开发完成后打成安装包文件,如果不希望被别人破解,通常会将代码进行混淆,从而让破解者难以阅读。
3. 分析项目如何运行
1 打开AndroidMainifest.xml 第一行代码 Android读书笔记(一)_第8张图片
这段代码表示对活动进行注册,没有在AndroidMainifest.xml里注册的活动是不能使用的。
2 分析活动代码
第一行代码 Android读书笔记(一)_第9张图片继承AppCompatActivity,这是一种向下兼容的Activity,可以将Activity在各个系统版本中增加的特性和功能最低兼容到Andriod2.1系统。Activity是Andriod系统的一个活动基类,项目中所有活动都必须继承它或者它的子类才能拥有活动的特性。onCreate这个方法是一个活动被创建时必定要执行的方法。
Android程序的设计讲究逻辑和视图分离,因此不推荐在活动中直接编写界面的,更加通用的一种做法是,在布局文件中编写界面,然后在活动中引入进来。
3 如何引用res目录下的内容
例如res/values/strings.xml。可以有两种方式进行引用。

  1. 在代码中通过R.string.name获得该字符串的引用
  2. 在xml中通过@string/name获得该字符串的引用。
    其中string部分是可以替换的,如果是引用的图片资源就可以换成drawable,如果引用的是应用图标就可以替换成mipmap,如果是引用的布局文件可以替换成layout
    4 详解build.gradle文件
    Gradle是一个非常先进的项目构建文件,它使用了一种基于Groovy的领域特定语言(DSL)来声明项目设置,摒弃了传统基于XML(如Ant和Maven)的各种繁琐配置。
    最外层的build.gradle

jcenter和google

dependencies闭包中使用了classpath声明了一个Gradle插件。
app目录下的build.gradle
apply plugin应用了一个插件,一般有两种值可选:com.android.application,表示这是一个应用程序模块,com.android.library表示这是一个库文件。应用程序模块和库模块的最大区别在于,一个是可以直接运行的,一个只能作为代码库依附于别的应用程序模块来运行。
compileSdkVersion用于指定项目的编译版本。buildToolsVersion用于指定项目构建工具的版本。
defaultConfig闭包中可以对项目的更多细节进行配置。applicationId用于指定项目的包名。minSdkVersion用于指定项目最低兼容的Android系统版本。targetSdkVersion指定的值表示你在该目标版本上已经做过充分的测试。
buildTypes闭包中用于指定生成完整文件的相关配置,通常会有两个子闭包,一个是debug,一个是release。debug闭包用于指定生成测试版安装文件的配置,release闭包用于指定生成正式版安装文件的配置。debug闭包是可以忽略不写的release闭包中minifyEnabled用于指定是否对项目的代码进行混淆,true代表混淆,false代表不混淆。proguardFiles用于指定混淆时使用的规则文件,这里指定了两个文件,第一个是proguard-android.txt是在Android SDK目录下的,里面是所有项目通用的混淆规则。第二个是proguard-rules.pro是在当前项目的根目录下的,里面可以编写当前项目特有的混淆规则。

掌握日志工具的使用

Android中的日志工具是Log(android.util.Log),这个类提供了如下5个方法来供我们打印日志。

  1. Log.v()。用于打印那些最为繁琐的、意义最小的日志信息。对应级别verbose,是Android日志里面级别最低的一种。
  2. Log.d()。用于打印一些调试信息,对应级别debug,比verbose高一级。
  3. Log.i()。用于打印一些比较重要的数据,可以分析用户行为数据,对应级别info,比debug高一级。
  4. Log.w()。用于打印一些警告信息,提示程序在这个地方可能会有潜在的风险,最好去修复一下这些出现警告的地方。对应级别warn,比info高一级。
  5. Log.e()。用于打印程序中的错误信息,当有错误信息打印出来,代表程序出现了严重问题,必须尽快修复。对应级别error,比warn高一级。

第二章 先从看得到的入手-探究活动

活动是什么

活动(Activity)是最容易吸引用户的地方,它是一种可以包含用户界面的组件,主要用于和用户进行交互。一个应用程序中可以包含零个或多个活动。

手动创建活动

右键new -activity- empty activity。
勾选Generate Layout File表示会自动创建一个对应的布局文件。
勾选LauncherActivity表示会自动将新创建的活动设置为当前项目的主活动。

创建和加载布局

Android程序的设计讲究逻辑和视图分离,最好每一个活动都能对应一个布局,布局就是用来显示界面内容的。
右击app/src/main/res目录->New->Directory,会弹出一个新建目录的窗口,起名为layout。右键->new ->Layout resources file,新建布局资源文件。
第一行代码 Android读书笔记(一)_第10张图片
Design是当前的可视化布局编辑器 ,在这里不仅可以预览当前的布局,还可以通过托放的方式编辑布局。而Text则是通过XML文件的方式来编辑布局。

    <Button            android:text=" Button 1"            android:layout_width="match_parent"            android:layout_height="wrap_content"             android:id="@+id/button_1"/>

match_parent表示让当前元素和父元素一样宽,wrap_content表示当前元素的高度只要能刚好包含里面的内容就行。
在活动里新增代码setContentView(R.layout.first_layout);setContentView()方法来给当前的活动加载一个布局。项目中添加的任何资源都会在R文件中生成一个相应的资源id。

注册活动以及配置主活动

所有的活动都要在AndroidManifest.xml中进行注册才能生效。Idea会自动帮忙注册。但是现在仍然不能运行程序,程序当前仍然没有配置主活动。
配置主活动的方法
在标签的内部加入

 <intent-filter>                <action android:name="android.intent.action.MAIN"/>                <category android:name="android.intent.category.LAUNCHER"/></intent-filter>

在活动中使用Toast

Toast是Android系统提供的一种提醒方式,在程序中可以使用它将一些短小的信息通知给用户,这些信息会在一段时间内后自动消失,并且不会占用任何屏幕空间。

 Button button1=(Button) findViewById(R.id.button_1);        button1.setOnClickListener(new View.OnClickListener(){            @Override            public void onClick(View v) {                Toast.makeText(FirstActivity.this,"you clicked",                        Toast.LENGTH_SHORT).show();            }        });

findViewById()可以获取到在布局文件中定义的元素,返回的是一个View对象,需要向下转型成Button对象。setOnClickListener()为按钮注册一个监听器,点击按钮时就会执行监听器的onClick()方法。
Toast的用法非常简单,通过静态方法makeText()创建出一个Toast对象,然后调用show()将Toast显示出来就可以。makeText()需要传入3个参数,第一个参数时Context,也就是Toast要求的上下文。第二个参数时Toast显示的文本内容,第三个参数时Toast显示的时长。

在活动中使用Menu

在res目录下新建一个menu文件夹,右键文件夹->new ->Menu resource file。
在新创建好的文件添加代码。

<item android:id="@+id/add_item" android:title="Add"/><item android:id="@+id/remove_item" android:title="Remove"/>

标签用来创建具体的某一个菜单项。
回到活动重写onCreateOptionsMenu()方法

  @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.main,menu);        return true;    }

getMenuInflater()方法可以获得MenuInflater对象,再调用它的inflate()方法就可以给当前活动创建菜单。inflate()方法接收两个参数,第一个参数用于指定我们通过哪一个资源文件来创建菜单。第二个参数用于指定菜单项将添加到哪一个Menu对象当中。返回值true,表示允许创建的菜单显示出来,如果返回false,创建的菜单将无法显示。

销毁活动

使用代码的方式:finish(),在活动中调用一下这个方法就可以销毁当前活动了。

使用Intent在活动之间穿梭

前提:
需要创建多个活动,以及布局。
什么是Intent
Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可用于启动活动、启动服务以及发送广播。
Intent大致可以分为两种:显式Intent和隐式Intent。
显示Intent的用法
Intent有多个构造函数的重载,其中一个是Intent(Context packageContext,Class<?> cls)。第一个参数Context要求提供一个启动活动的上下文,第二个参数Class则是指定想要启动的目标活动。Activity类中提供了一个startActivity()方法,这个方法是专门用于启动活动的。

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

隐式Intent的用法
它并不明确的指出要启动哪一个活动,而是指定了一系列更为抽象的action和category等信息,然后交由系统分析Intent,找出合适的活动。
AndroidManifest.xml当中为要跳转的页面添加代码

  <activity android:name=".SecondActivity">            <intent-filter>                <action android:name="com.example.activityTest.ACTION_START"/>                <category android:name="android.intent.category.DEFAULT"/>            </intent-filter>        </activity>

只有和中的内容同时能够匹配上Intent中指定的action和category时,这个活动才能响应该Intent。
此处没有指定category的原因在于android.intent.category.DEFAULT是一种默认的category,在调用startActivity()方法时会自动将这个category添加到Intent中。
每个Intent中只能确定一个action,但却能指定多个category。
指定category的方法

Intent intent=new Intent("com.example.activityTest.ACTION_START");intent.addCategory("com.example.activitytest.My");startActivity(intent);

更多隐式Intent的用法

使用隐式Intent,不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这使得Android多个应用程序之间的功能共享成为了可能。

Intent intent=new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("https://www.baidu.com/"));startActivity(intent);

在标签中可以再配置一个标签,用于更精准的指定当前活动能够响应什么类型的数据。

  • android:scheme。用于指定数据的协议部分。如http,geo地理位置,tel表示被打电话。
  • android:host。用于指定数据的主机名部分。
  • android:port。用于指定数据的端口部分。
  • android:path。用于指定主机名和端口之后的部分。
  • android:mimeType。用于指定可以处理的数据类型,允许使用通配符的方式进行指定。
    只有标签中指定的内容和Intent中携带的Data完全一致时,当前活动才能响应该Intent。
 Intent intent=new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("tel:10086"));startActivity(intent);

向活动传递数据

向下一个活动传递数据
在启动活动时传递的数据暂存在Intent中,启动了另一个活动后,只需要把这些数据再从Intent中取出就可以了。
在跳转前的活动页面当中

 String data="Hello !"; Intent intent=new Intent(FirstActivity.this,SecondActivity.class); intent.putExtra("data",data);

putExtra()方法接收两个参数,第一个参数是键,用于后面从Intent中取值,第二个参数才是真正要传递的数据。
在跳转后的页面当中

  Intent intent=getIntent();  String data=intent.getStringExtra("data");  Log.d("SecondActivity",data);

如果传递的是整型数据,则使用getIntExtra()方法,如果传递的是布尔型数据,则使用getBooleanExtra()方法
向上一个活动传递数据
Activity中还有一个startActivityForResult()方法也是用于启动活动的,但是这个方法期望在活动销毁的时候能够返回一个结果给上一个活动。
第一个活动的代码如下

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

startActivityForResult()方法接收两个参数,第一个参数是Intent,第二个参数是请求码,用于在之后的回调中判断数据的来源。
第二个代码如下

@Override    public void onBackPressed() {        Intent intent=new Intent();        intent.putExtra("data_return","he");        setResult(RESULT_OK,intent);        finish();    }

当用户按下Back键,就会去执行onBackPressed()方法中的代码。setResult()是专门用于向上一个活动返回数据的。第一个参数用于向上一个活动返回处理结果,一般只使用RESULT_OK或RESULT_CANCELED这两个值,第二个参数则把带有数据的Intent
在第一个活动当中添加

  @Override    protected void onActivityResult(int requestCode, int resultCode,  Intent data) {        super.onActivityResult(requestCode, resultCode, data);        switch (requestCode) {            case 1:                if (resultCode == RESULT_OK) {                    String returnedData = data.getStringExtra("data_return");                    Log.d("FirstActivity", returnedData);                }                break;            default:        }    }

由于是使用startActivityForResult()方法来启动SecondActivity的,在SecondActivity被销毁之后会回调上一个活动的onActivityResult()方法。

活动的生命周期

返回栈
Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称为返回栈。在默认的情况下,每当新启动了一个活动,它就会在返回栈中入栈,并处于栈顶的位置。而每当按下Back键或调用finish()方法来销毁一个活动时,处于栈顶的活动会出栈。系统总是会显示处于栈顶的活动给用户。
活动状态
每个活动在其生命周期中最多会有4种状态。

  1. 运行状态
    当一个活动位于返回栈的栈顶时,这时活动处于运行状态。系统最不愿意回收的就是处于运行状态的活动,因为这会带来非常差的用户体验。
  2. 暂停状态
    当一个活动不再处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态。并不是每一个活动都会占满整个屏幕的,比如对话框形式的活动只会占用屏幕中间的部分区域。处于暂停状态的活动仍然时存活的,系统也不愿意去回收这种活动(因为它还是可见的,回收可见的东西都会在用户体验方面有不好的影响),只有在内存极低的情况下,系统才会去考虑回收这种活动
  3. 停止状态
    当一个活动不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态,系统仍然会为这种状态保存相应的状态和成员变量,但是这并不是完全可靠的,当有其他地方需要内存时,处于停止状态的活动有可能会被系统回收。
  4. 销毁状态
    当一个活动从返回栈移除后就变成了销毁状态,系统会最倾向于回收处于这种状态的活动,从而保证手机的内存充足。
    ** 活动的生存期**
    Activity类中定义了7个回调方法,覆盖了活动生命周期的每一个环节。
  • onCreate()。它会在活动第一次被创建的时候调用,在这个方法中完成活动的初始化操作,比如说加载布局,绑定事件等。
  • onStart()。这个方法在活动由不可见变为可见的时候调用。
  • onResume()。这个方法在活动准备好和用户进行交互时使用。此时的活动一定位于返回栈的栈顶。并且处于运行状态。
  • onPause()。这个方法在系统准备去启动或者恢复另一个活动的时候调用。通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据。但这个方法所谓执行速度一定要块,不然会影响到新的栈顶活动的使用。
  • onStop()。这个方法会在活动完全不可见的时候调用。它和onPause()方法的主要区别在于,如果启动的新活动是一个对话框的式的活动,那么onPause()方法会得到执行,而onStop()方法并不会执行。
  • onDestory()。这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。
  • onRestart()。这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。
    可以将活动分为3种生存期。
    1 完整生存期。活动在onCreate()方法和onDestory()方法之间所经历的,就是完整生存期。一般情况下一个活动会在onCreate()方法中完成各种初始化操作,而在onDestory方法中完成释放内存的操作。
    2 可见生存期。活动在onStart()方法和onStop()方法之间所经历的,就是可见生存期。在可见生存期内,活动对于用户总是可见的,即便有可能无法和用户进行交互,仍然可以通过这两个方法,合理地管理对用户可见的资源。比如在onStart()方法中对资源进行加载,而在onStop()方法中对资源进行释放,从而保证处于停止状态的活动不会占用过多内存。
    3 前台生存期。活动onResume()方法和onPause()方法之间所经历的就是前台生存期。在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行交互的。

活动被回收了怎么办

Activity中还提供了一个onSaveInstanceState()回调方法,这个方法可以保证在活动被回收之前一定会被调用。可以通过这个方法来解决活动被回收时临时数据得不到保存的问题。

 @Override    protected void onSaveInstanceState(@NonNull Bundle outState) {        super.onSaveInstanceState(outState);        String tempData="Something you just typed";        outState.putString("data_key",tempData);    }

onSaveInstanceState()方法会携带一个Bundle类型的参数,Bundle提供了一系列的方法用于保存数据,比如可以使用putString()方法保存字符串。
如何恢复保存下来的数据
onCreate()方法其实也有一个Bundle类型的参数,这个参数一般情况下都是null,但是如果在活动被系统回收之前有通过onSaveInstanceState()方法来保存数据的话,这个参数就会带有之前所保存的全部数据。

 @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        if(savedInstanceState!=null)        {            String tempData=savedInstanceState.getString("data_key");            Log.d("tag",tempData);        }    }

Intent可以结合Bundle一起用于传递数据,可以把需要传递的数据都保存在Bundle对象中,然后再将Bundle对象存放在Intent里。到了目标活动之后再从Intent中取出Bundle。

活动的启动模式

活动的启动模式一共有4种,分别是standard、singleTop、singleTask和singleInstance,可以在AndroidManifest.xml中通过给标签指定android:launchMode属性来选择启动模式。
standard
standard是活动默认的启动模式,在不进行显式指定的情况下,所有的活动都会自动使用这种启动模式。在standard模式(即默认情况)下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。
singleTop
当活动的启动模式指定为singleTop,在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会在创建新的活动实例。但当活动并未处于栈顶位置时,这时再启动活动,还是会创建新的实例的。
singleTask
当活动的启动模式指定为singleTask,每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。
singleInstance
singleInstance模式的活动会启用一个新的返回栈来管理这个活动。程序中有一个活动是允许其他程序调用的,想实现其他程序和我们的程序可以共享这个活动的实例,可以使用singleInstance模式进行解决,这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。
第一行代码 Android读书笔记(一)_第11张图片

活动的最佳实践

知晓当前是在哪一个活动
新增一个基础类,该类是简单的java class而不是新增空白活动,代码如下。

public class BaseActivity extends AppCompatActivity {    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Log.d("BaseActivity",getClass().getSimpleName());    }}

更改之前的activity的继承体系,改为继承BasicActivity。这样每当进入一个活动的界面,该活动的类名就会被打印出来。
随时随地退出程序
如果一个程序已经打开了许多活动,此时退出程序是非常不方便的,需要连按许多次Back,按Home只是把程序挂起,并没有退出程序。
需要一个专门的集合类对所有的活动进行管理。

public class ActivityCollector {    public static List<Activity> activities =new ArrayList<>();    public static void addActivity(Activity activity){        activities.add(activity);    }    public static void removeActivity(Activity activity){        activities.remove(activity);    }    public static void finishAll(){        for(Activity activity:activities){            if(!activity.isFinishing())                activity.finish();        }    }}

onCreate创建活动时使用addActivity方法,当onDestory销毁活动时调用removeActivity方法。当想强制退出时调用finishAll方法。
还可以在销毁所有活动的代码后面再加上杀掉当前进程的代码,以保证程序完全退出。
android.os.Process.killProcess(android.os.Process.myPid())
killProcess()方法用于杀掉一个进程,它接收一个进程id参数,myPid()方法用于获得当前程序的进程id。killProcess()方法只能用于杀掉当前程序的进程,不能使用这个方法去杀掉其他程序。
启动活动的最佳写法

  public static void actionStart(Context context,String data1,String data2){        Intent intent=new Intent(context,SecondActivity.class);        intent.putExtra("param1",data1);        intent.putExtra("param2",data2);        context.startActivity(intent);    }

通过调用函数,能够较为直观的得知传递了什么参数。

更多相关文章

  1. Android Studio GitHub 提交项目代码
  2. 【初用Android Studio】快捷键之代码提示
  3. Android 解决65535的限制 使用android-support-multidex解决Dex
  4. Android 应用语言切换的三种方法
  5. Android CheckBox中设置padding无效问题解决方法
  6. Android项目文件结构
  7. Android与JS代码交互
  8. Android设备Root检测方法
  9. Android Studio中创建Selector文件的方法

随机推荐

  1. Android的UI结构试图工具hierarchyviewer
  2. 详解android:scaleType属性
  3. Android(安卓)Activity动画属性简介
  4. Android(安卓)API中文文档(111) —— Mai
  5. android:layout_marginLeft等的简单用法
  6. Android(安卓)API中文文档系列Manifest
  7. android中adb命令大全
  8. 【android乱七八糟】android体系结构
  9. android 电池(三):android电池系统
  10. Mac 配置Android环境变量( 有图)