IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android开发自学-持续更新(安卓逆向基础) -> 正文阅读

[移动开发]Android开发自学-持续更新(安卓逆向基础)







学习目标:

由于研究生阶段的目标需要,现目前对安卓开发进行学习,因为以前对安卓开发并没有基础,只有java语言基础,但是所幸安卓开发主要是使用JAVA语言,所以现在对安卓进行自学,但是由于主要研究方向是安卓逆向分析,所以对安卓开发并不会太细,只是基于安卓的基础上,看得懂代码,自己能够写出代码,能够完整地分析出一个项目,主要方向还是在安卓逆行分析上!

主要参考书籍:《第一行代码》

主要学习工具:Android Studio




学习内容:

目录

一、了解Android

二、安卓应用开发的关键-活动(Activity)

1.使用按钮创建声明活动

?2.使用菜单Menu

3.使用Intent在活动之间穿梭

?3.1使用显示intent

?3.2 使用隐式intent

?3.3 更多隐式intent的用法

?3.4? 利用intent传递数据

?3.5 返回数据给上一个活动

3.6 活动的生命周期

三? UI设计



一、了解Android

1、安卓大致分为四层架构,由于本人的需求是逆向分析,所以在安卓的应用层和linux内核层会有侧重。

?2、Android应用开发特色

2.1? 四大组件

Activity(活动)Service(服务)Broadcast Recevier(广播接收器)Content Recevier(内容提供器)

其中活动是Android应用的门面,凡是在应用中你所看到的所有东西,都放在了活动中!

2.2 系统控件

Android为开发者提供了丰富的系统控件,使得开发者可以自己开发出漂亮的用户界面,如果你不满足于系统控件,也可以使用属于自己的控件。

2.3 SQLite数据库

Android系统还自带了这种轻量级的、运算速度极快的嵌入式关系型数据库。

2.4 强大的自媒体

Android系统还提供了丰富的自媒体服务,如音乐,服务,视频,录音,闹钟等等,让你的应用变得丰富多彩。

2.5 地理位置定位

Android手机有内置的gps,可以定位自己的位置。

二、安卓应用开发的关键-活动(Activity)

1.使用按钮创建声明活动

点击Package,然后鼠标直接戳,创建活动,这些简单的就不一一记录了,直接进入代码,每次创建活动,都会有创建布局文件,可以自己选择是否自动生成,不自动生产也可以自己点击res包中自己生产xml布局文件。

当你创建好活动以后查看源代码,会发现已经重写了OnCreate()方法了。

对布局的创建,这里不一一详细介绍,那个比较容易上手和记忆,所以我们现在主要介绍活动层的编写,这里只介绍布局文件中与后面活动层有关的内容,比如我们在布局文件中创建一个Button按钮,id为button_1,这个id就是最关键的,与后端活动进行交互主要是基于这个id,android:id是给当前的元素定义一个唯一标识符,相当于给他取一个名字。

按钮创建好以后,我们接下来应该做的是,在活动中加载这个布局,使用setContentView()方法来加载一个布局,传入这个布局文件的id值即可,记住是以R.xxx.xxx的方式来传值,这是规矩。

?接下来,就是在AndroidManifest.xml文件中注册,任何活动都要在这个文件中进行注册以后才可以生效,当然,集成工具已经给你自动注册好了,但是仅仅是注册活动,程序仍然是不能够使用的,因为还没有为程序配置主活动,程序运行起来的时候,还不知道启动哪个活动。

下图中的<intent-filter>标签就是配置主活动的操作,通过添加action和category这两句声明即可。

?

在活动中添加Toast声明,在程序中使用这个声明对用户进行一个提醒。查看此程序可以看到,通过findViewByid()这个方法可以找到布局中的Button按钮的id,获取到这个布局的元素,然后对其进行向下转型成为一个button对象,然后用button对象调用一个setOnClickListener()方法,执行监听,用户点击按钮以后,就会执行监听器中的OnClick()的方法了。

其中Toast方法很简单,通过静态方法makeText()方法创建出一个Toast对象,然后调用show()方法让他显示出来就可以了。Toast.makeText()方法需要传入三个参数,第一个参数是ConText,也就是Toast要求的上下文,由于这个活动本身就是一个Context对象,因此这里直接写入MainActivity.this就可以了,第二个参数是该声明需要显示的内容,第三个是声明显示的时长。

?2.使用菜单Menu

?创建出相应的Menu布局文件以后,在布局文件中使用item标签创建菜单项,<item>标签就是用来

创建一个具体的菜单项的。

?然后回到主活动中去重写onCreateOptionsMenu()方法,编写如图下代码,

?但是就仅仅创造出菜单是不够用的,我们还要创造菜单相应事件,重新onOptionsItemSelected()方法

3.使用Intent在活动之间穿梭

怎样从一个活动跳转到另一个活动呢,这就需要使用到intent活动了。

?3.1使用显示intent

使用鼠标之直接戳,在Package里面创建第二个活动,并且同时创建布局文件,设置好布局文件中的第二个按钮以后,另外不要忘记任何活动都要在AndroidManifest.xml文件中注册的,点开这个文件以后发现集成工具已经给我们生成好了,由于这个活动并不是主活动,所以不需要配置<intent-filter>里面的内容。

Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想
要执行的动作,还可以在不同组件之间传递数据。Intent 一般可被用于启动活动、启动服务以及
发送广播等场景,由于服务、广播等概念你暂时还未涉及,那么本章我们的目光无疑就锁定在了
启动活动上面。
Intent有多个构造函数的重载,其中一个是Intent (Context packageContext, Class<?>
cls)。这个构造函数接收两个参数,第一个参数Context要求提供一个 启动活动的上下文,第
二个参数Class则是指定想要启动的目标活动,通过这个构造函数就可以构建出Intent的“意
图”。然后我们应该怎么使用这个Intent呢? Activity 类中提供了一个startActivity()方法,这
个方法是专门用于启动活动的,它接收一个Intent参数,这里我们将构建好的Intent 传入
startActivity( )方法就可以启动目标活动了。

?3.2 使用隐式intent

与显示Intent相比的话,隐式intent就含蓄了许多,他不会明确地指出我们想要启动哪一个活动,而是指定了一系列的action和category等信息,交给系统去分析这个intent,并且启动。

在action中我们指明了当前活动可以相应com.example.practice.ACTION_START这个action,而category里面附加了一些信息,更精确地指出了当前的活动能够响应的intent,只有同时匹配上这个action和category,这个活动才能响应intent。

但是你会发现我们这里只匹配了action啊,category怎么没匹配呢,这是因为android.intent.category.DEFAULT是一种默认的category,不需要匹配。

但是如果你添加了其他的category时,需要在AndroidManifest.xml中添加匹配的category。

?

?3.3 更多隐式intent的用法

使用隐式Intent,我们不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这使
得Android多个应用程序之间的功能共享成为了可能。比如说你的应用程序中需要展示一个网页,
这时你没有必要自己去实现一个浏览器(事实上也不太可能),而是只需要调用系统的浏览器来
打开这个网页就行了。

同时在配置文件中修改action和category两个地方,如下

但是除了http协议以外,我们还可以指定其他协议,,不如geo显示地理位置,tel表示拨打电话,修改代码如下图,并且修改安卓的注册文件,

?3.4? 利用intent传递数据

我们现在都只是简单地运用了 Intent,其实还有很多种用法,可以使用intent传递数据,,提供了一系列putExtra()方法重载,可以把我们想传递的数据暂存在intent中,启动了另一个活动后,再从这个intent中取出来就好了。编写好主活动和次活动以后的布局文件以后,修改点击按钮的监听器,

这里我们还是使用显式Intent 的方式来启动SecondActivity,并通过putExtra()方法传递了
-一个字符串。注意这里putExtra()方法接收两个参数,第一个参数是键,用于后面从Intent中.
取值,第二个参数才是真正要传递的数据。
然后我们在SecondActivity中将传递的数据取出,并打印出来,代码如下所示:

首先可以通过getIntent() 方法获取到用于启动SecondActivity 的Intent, 然后调用
getString Extra()方法, 传人相应的键值,就可以得到传递的数据了。这里由于我们传递的
是字符串,所以使用getStringExtra()方法来 获取传递的数据。如果传递的是整型数据,则
使用getIntExtra()方法;如果传递的是布尔型数据,则使用getBooleanExtra()方法, 以
此类推。

?3.5 返回数据给上一个活动

既然可以传递数据给下一个活动,那么能不能够返回数据给上-一个活动呢?答案是肯定的。
不过不同的是,返回上一个活动只需要按一~下Back键就可以了,并没有一一个用于启动活动Intent
来传递数据。通过查阅文档你会发现,Activity 中还有-一个startActivityForResult()方法也
是用于启动活动的,但这个方法期望在活动销毁的时候能够返回-个结果给上一个活动。毫无疑
问,这就是我们所需要的。
startActivityForResult()方法接收两个参数,第-一个参数还是Intent, 第二个参数是请
求码,用于在之后的回调中判断数据的来源。我们还是来实战一下,修改FirstActivity中按钮的
点击事件,代码如下所示:

然后我们再在第二个活动中添加按钮监听器,代码如下:

可以看到,我们还是创建了一个intent对象,但是这个intent仅仅用于存放数据而已,没有指定任何意图,把数据存放在intent以后,再调用了setResult()方法,这个方法非常重要,主要是向上一个活动返回数据的,setResult()接收了两个参数,第一个参数是向上一个活动返回处理结果的,一般只适用RESULT_OK或者是RESULT_CANCELED这两个值,第二个参数值intent则把数据返回到上一个活动,最后调用了finish()方法来销毁当前活动。

?由于我们是使用startActivityForResult ( )方法来启动SecondActivity的,在SecondActivity
被销毁之后会回调上一个活动的onActivityResult()方法,因此我们需要在FirstActivity 中重
写这个方法来得到返回的数据,如下所示:

onActivityResult()方法带有三个参数,第一个参数requestCode,即我们在启动活动时
传人的请求码。第二个参数resultCode, 即我们在返回数据时传人的处理结果。第三个参数
data,即携带着返回数据的Intent。由于在一个活动中有可能调用startActivityForResult()
方法去启动很多不同的活动, 每一 个活动返回的数据都会回调到onActivityResult()这个方法
中,因此我们首先要做的就是通过检查requestCode的值来判断数据来源。确定数据是从
SecondActivity返回的之后,我们再通过resultCode的值来判断处理结果是否成功。最后从data
中取值并打印出来,这样就完成了向上一个活动返回数据的工作。

这时候你可能会问,如果用户在SecondActivity中并不是通过点击按钮,而是通过按下Back
键回到FirstActivity, 这样数据不就没法返回了吗?没错,不过这种情况还是很好处理的,我们
可以通过在SecondActivity中重写onBackPressed()方法来解决这个问题,代码如下所示:

?

?这样按下返回键以后,查看logcat就会发现返回的消息。

3.6 活动的生命周期

掌握活动的生命周期对任何Android开发者来说都非常重要,当你深人理解活动的生命周期
之后,就可以写出更加连贯流畅的程序,并在如何合理管理应用资源方面发挥得游刃有余。你的
应用程序将会拥有更好的用户体验。
其实Android是使用任务( Task )来管理活动的,一个任务就是一-组存放 在栈里的活动的集
合,这个栈也被称作返回栈( Back Stack)。栈是一种后进先出的数据结构,在默认情况下,每当
我们启动了一个新的活动,它会在返回栈中人栈,并处于栈项的位置。而每当我们按下Back键
或调用finish()方法去销毁-一个活动时,处于栈顶的活动会出栈,这时前一-个人栈的活动就会
重新处于栈顶的位置。系统总是会显示处于栈顶的活动给用户。
Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称为返回栈,栈的数据结构就不多介绍了,每开启一个新的活动时,这个新活动就会入栈,处于栈顶位置,然而用返回键或者是finish()方法销毁一个活动时,处于栈顶的活动都会出栈,前一个入栈的活动就会重新处于栈顶位置,系统总会显示处于栈顶的活动给用户,如下图。?

?3.6.1 活动状态

每个活动在其生命周期最多有4种状态。

1、运行状态

当一个活动位于返回栈的栈顶时,这时活动就处于运行状态。系统最不愿意回收的就是处于
运行状态的活动,因为这会带来非常差的用户体验。
2、暂停状态

当一个活动不再处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态。你可能会觉得
既然活动已经不在栈顶了,还怎么会可见呢?这是因为并不是每一个活动都会占满整个屏幕的,
比如对话框形式的活动只会占用屏幕中间的部分区域,你很快就会在后面看到这种活动。处于暂
停状态的活动仍然是完全存活着的,系统也不愿意去回收这种活动(因为它还是可见的,回收可
见的东西都会在用户体验方面有不好的影响),只有在内存极低的情况下,系统才会去考虑回收
这种活动。

3、停止状态

当一个活动不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。系统仍然会为
这种活动保存相应的状态和成员变量,但是这并不是完全可靠的,当其他地方需要内存时,处于
停止状态的活动有可能会被系统回收。
4、销毁状态

当一个活动从返回栈中移除后就变成了销毁状态。系统会最倾向于回收处于这种状态的活
动,从而保证手机的内存充足。
3.6.2? 活动的生存期

Activity类中定义了7个回调方法,覆盖了活动生命周期的每一个环节,下面就来----介绍
这7个方法。

onCreate():这个方法你已经看到过很多次了,每个活动中我们都重写了这个方法,它
会在活动第一次被创建的时候调用。你应该在这个方法中完成活动的初始化操作,比如
说加载布局、绑定事件等。
onStart():这个方法在活动由不可见变为可见的时候调用。
onResume():这个方法在活动准备好和用户进行交互的时候调用。此时的活动- -定位于
返回栈的栈顶,并且处于运行状态。
onPause():这个方法在系统准备去启动或者恢复另一个活动的时候调用。我们通常会在
这个方法中将- - 些消耗CPU的资源释放掉,以及保存- -些关键数据,但这个方法的执行
速度一定要快,不然会影响到新的栈顶活动的使用。
onStop():这个方法在活动完全不可见的时候调用。它和onPause()方法的主要区别在
于,如果启动的新活动是一一个对话框式的活动,那么onPause()方法会得到执行,而
onStop():方法并不会执行。
onDestroy():这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。
onRestart():这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新
启动了。

以上7个办法,除了onRestart()以外,其他都是两两相对的,从而把活动分为三种生存期。

完整生存期:活动在onCreate()方法和onDestroy( )方法之间所经历的,就是完整生存
期。一般情况下,一个活动会在onCreate()方法中完成各种初始化操作,而在
onDestroy()方法中完成释放内存的操作。
可见生存期:活动在onStart()方法和onStop()方法之间所经历的,就是可见生存期。
在可见生存期内,活动对于用户总是可见的,即便有可能无法和用户进行交互。我们可
以通过这两个方法,合理地管理那些对用户可见的资源。比如在onStart()方法中对资
源进行加载,而在onStop()方法中对资源进行释放,从而保证处于停止状态的活动不会
占用过多内存。
前台生存期:活动在onResume()方法和onPause()方法之间所经历的就是前台生存期。
在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行交互的,我
们平时看到和接触最多的也就是这个状态下的活动。

3.6.3? 活动被回收了怎么办?

前面我们已经说过,当-一个活动进入到了停止状态,是有可能被系统回收的。那么想象以下
场景:应用中有-一个活动A,用户在活动A的基础上启动了活动B,活动A就进入了停止状态,
这个时候由于系统内存不足,将活动A回收掉了,然后用户按下Back键返回活动A,会出现什
么情况呢?其实还是会正常显示活动A的,只不过这时并不会执行onRestart()方法,而是会
执行活动A的onCreate()方法,因为活动A在这种情况下会被重新创建-一次。
这样看上去好像-一切正常,可是别忽略了一个重要问题,活动A中是可能存在临时数据和
状态的。打个比方,MainActivity 中有一个文本输人框,现在你输入了一段文字,然后启动
NormalActivity,这时MainActivity由于系统内存不足被回收掉,过了一会你又点击了Back键回
到MainActivity,你会发现刚刚输人的文字全部都没了,因为MainActivity被重新创建了。
如果我们的应用出现了这种情况,是会严重影响用户体验的,所以必须要想想办法解决这个
问题。查阅文档可以看出,Activity 中还提供了一个onSaveInstanceState()回调方法,这个方
法可以保证在活动被回收之前--定会被调用,因此我们可以通过这个方法来解决活动被回收时临
时数据得不到保存的问题。
onSaveInstanceState()方法会携带一个Bundle类型的参数,Bundle 提供了一系列的方
法用于保存数据,比如可以使用putString()方法保存字符串,使用putInt()方法保存整型数
据,以此类推。每个保存方法需要传人两个参数,第-一个参数是键,用于后面从Bundle中取值,第二个参数才是真正要保存的内容。

数据是已经保存下来了,那么我们应该在哪里进行恢复呢?细心的你也许早就发现,我们一
直使用的onCreate()方法其实也有一个Bundle类型的参数。这个参数在- -般情况下都是null,
但是如果在活动被系统回收之前有通过onSaveInstanceState( )方法来保存数据的话,这个参
数就会带有之前所保存的全部数据,我们只需要再通过相应的取值方法将数据取出即可。
(这一节理解起来有点困难,以后再详细补充)

3.7 活动的启动模式

在项目中我们应该需求的不同而选择不同的活动启动模式。启动模式一共有四种:standard、singletop、singletask、和singleinstance,可以在配置文件中选择不同的属性来启动活动。

其中SingleInstance最为复杂,需要多加理解。

三? UI设计

由于本人侧重点不在前端UI设计,主要侧重于后端代码分析,所以在这里不详细介绍。








学习时间:

2021.11.17

2021.11.18








学习产出:

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-19 17:44:27  更:2021-11-19 17:45:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:45:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码