了解安卓开发

了解安卓开发

Log类

级别:

  • e:错误
  • w:警告
  • i:一般
  • d:调试
  • v:冗余

APP工程目录结构

App工程分为两个层次,第一个层次是项目,第二个层次是模块,模块依附于项目,每个项目至少有一个模块,也能拥有多个模块。一般说的变异运行APP指的是运行某个模块,而非整个项目,因为模块才对应实际的APP。

其中目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- app
- manifests:是APP的运行配置文件
- java:里面有三个com.muapp.exapmle包,只有第一个是源文件,其余的是测试文件
- res:资源文件
- drawable:图标
- layout:布局文件
- mipmap:启动图标
- values:设置常量,例如颜色,等
- themes:主题
- Gradle Scripts
- build.dradle:全局配置,描述编译规则
- build.dradle:模块配置,描述编译规则
- proguard-rules.pro:用于描述java代码的混淆规则,有利于提升安卓应用的安全性
- gradsel.properties:用于配置编译工程的命令行参数
- settings.gradel:配置了需要编译哪些模块
- local.properties:项目的本地配置文件,用于描述电脑的环境配置,包括SDK本地路径,NDK本地路径等

什么是Gradle,类似于webpack,是一种自动化构建工具,用于将代码应用打包,部署等工作。

Activity

本质上Activity就是一个页面组件,可以理解为提供一个屏幕,用户再上面完成交互。

创建与跳转

完整的页面创建需要经历一下三个步骤:

  • 在layout目录下创建XML文件
  • 创建与XML文件对应的java代码
  • 在AndroidManifest.xml中注册页面配置

简单控件

设置文本内容的两种方式

  • XML文件中属性android:text设置文本
  • Java代码中通过setText方式设置文本

设置字体大小

  • textSize
  • setTextSize
    单位尺寸的一些知识:
  • px:逻辑像素
  • Resolution:分辨率
  • Dpi:像素密度

设置文本颜色

  • textColor
  • setTextColor
    Color类来表示颜色,绿色:Color.GREEN

设置视图的宽高

单位

在安卓开发中,我们使用一些常见的单位来测量和布局屏幕上的元素。以下是一些常见的安卓开发单位:

  1. 像素(Pixel,px):像素是屏幕上最小的可见点。在安卓开发中,屏幕上的元素通常以像素为单位进行测量和定位。

  2. 密度无关像素(Density Independent Pixel,dp或dip):dp是一种与设备密度无关的单位,它确保了在不同的屏幕密度下元素的尺寸保持一致。在不同的设备上,1dp会根据设备的屏幕密度进行自适应调整。

  3. 独立比例像素(Scale Independent Pixel,sp):sp与dp类似,但在字体大小方面更为常用。它会根据用户的字体大小首选项进行自适应调整,确保字体在不同设备上具有一致的可读性。

  4. 英寸(Inch,in):英寸是长度单位,用于测量屏幕的物理尺寸。它通常与屏幕分辨率结合使用,以计算像素密度等信息。

  5. 毫米(Millimeter,mm):毫米也是一种长度单位,常用于测量设备的物理尺寸。

  6. 点(Point,pt):点是一种常见的打印和排版单位,也可以在安卓开发中使用。它与像素之间存在一定的关系,但在不同的设备上可能会有一些差异。

在安卓开发中,使用合适的单位可以帮助我们实现屏幕适配和元素布局的灵活性和一致性。根据具体的需求和设计,选择合适的单位可以确保应用程序在不同的设备上以一致的方式呈现。

ViewGroup

LinearLayout线性布局

属性介绍:

  • origentation:布局中组件的排列方式
  • gravity:组件中子元素的对其方式
  • layout_gravity:该组件在父容器中的对其方式
  • layout_width:布局的宽度
  • layout_height:高度
  • weight:权重

RelativeLayout相对布局

可以相对于父级也可以相对于兄弟元素。

TableLayout表格布局

FrameLayout帧布局

GridLayout网格布局

常用的属性:

  • android:layout_row:行索引
  • android:layout_column:列索引
  • android:layout_rowSpan:组件跨域的行数
  • android:layout_gravity:组件在网格中的对其方式
  • android:layout_rowCount:设置行数

Activity生命周期

Activity表现为四种状态:

  • 活动状态Active:Activity在用户界面中处于最上层,完全能被用户看到,能够与用户进行交互。
  • 暂停状态Pause:Activity在界面上被部分遮挡,不再处于用户界面的最上层,且不能够与用户进行交互。(如弹出选择框时)
  • 停止状态Stop:Activity被其他Activity全部遮挡,界面完全不能被用户看到。(如玩游戏时来电了)
  • 非活动状态Dead:Activity没有启动或者被finish()。
    随着Activity自身状态的变化,Android系统会调用不同的
    事件回调函数(7个):
    1
    2
    3
    4
    5
    6
    7
    protected void onCreate(Bundle savedInstanceState); 
    protected void onStart(); // 显示在屏幕上时
    protected void onRestart(); // stop状态进入start状态
    protected void onResume(); // 用户可以交互时
    protected void onPause(); // 弹窗
    protected void onStop(); // 玩游戏来电话
    protected void onDestroy(); // 销毁
    p9bvVTH.png

启动模式

Stander(默认模式)

每次调用Activity时都会创建一个新的实例,并将其放入活动栈中,无论Activity否存在,都会创建新的实例

SingleTop(栈顶复用)

只有栈顶的Activity会复用,只更新意图(intent),不会重新创建新的实例

SingleTask(栈内复用)

于singleTop类似,只不过前者策略是:如果栈中存在目标Activity实例,则将任务栈中的在目标Activity实例之上的所有任务弹出。

SignalInstance(全局唯一模式)

会为每个实例都创建一个任务栈,然后复用

启动标志

通过调用Intent类的setFlags()方法来设置。

1
2
3
4
5
6
7
8
9
10
11
FLAG_ACTIVITY_NEW_TASK:将Activity启动为一个新的任务。如果当前没有任务栈存在,则会创建一个新的任务栈,如果已经存在任务栈,则该Activity会被添加到已存在的任务栈中。

FLAG_ACTIVITY_CLEAR_TOP:如果目标Activity已经在任务栈中存在,那么会将该Activity之上的所有Activity实例移除,并将该Activity置于栈顶。这样可以避免在同一个任务栈中创建多个相同的Activity实例。

FLAG_ACTIVITY_SINGLE_TOP:如果目标Activity已经在任务栈的栈顶,那么不会创建新的Activity实例,而是调用目标Activity的onNewIntent()方法来传递新的Intent。

FLAG_ACTIVITY_CLEAR_TASK:清除任务栈中的所有Activity实例,并且将目标Activity作为新的任务栈的栈底。

FLAG_ACTIVITY_NO_HISTORY:启动Activity时,不在任务栈中保留该Activity的实例。当用户离开该Activity时,该Activity实例会被立即销毁。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:启动的Activity不会出现在最近任务列表中。

一些基本的组件

  • TextView
  • ImageView
    1
    2
    ImageView iv=(ImageView)findViewById(R.id.imageView); iv.setImageResource(R.drawable.bg320_480);	//根据id值加载图片 iv.setVisibility( View.INVISIBLE );	//图片不可见
    可见:View.VISIBLE 注:VISIBLE值为0,INVISIBLE为4
  • Button
    1
    2
    3
    4
    5
    6
    7
    8
    // 添加点击事件
    Button bt=(Button)findViewById(R.id.button); bt.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    // 代码
    }
    });

  • ImageButton
  • ToggleButton 打开和关闭的那种二状态按钮
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ToggleButton tb=(ToggleButton)findViewById(R.id.toggleButton); tb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){
    if( isChecked ){
    // 开关开启
    }
    else{
    // 开关关闭
    }
    }
    })
  • EditText
    1
    2
    3
    EditText et=(EditText)findViewById(R.id.editText);
    et.setText("hello");
    String msg=et.getText().toString(); //toString()转换为字符串
  • RadioButton 单选按钮需归入一个Group,每个组中只有一个能选中。
    p9qpCUe.png
  • CheckBox
  • Spinner下拉列表
  • ListView

Adapter适配器

适配器就是数据对于视图的一个转换映射
以ArrayAdapter为例:

  1. 定义数据集
    1
    String[] data = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"};
  2. 创建Adapter
    1
    2
    ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, data);
    // 其中参数:上下文、一种自带的布局模式、数据集
  3. 绑定适配器
    1
    2
    ListView listView = findViewById(R.id.listView);
    listView.setAdapter(adapter);

Intent

Intent是一种组件之间消息传递机制,他是一个动作的完整描述:包含了动作产生组件、接收组件和传递的数据信息。
p9qeP1O.png
主要用途:启动Activity、Service、发布广播

Intent意图

是各个组件之间信息沟通的桥梁

显示Intent

1
2
Intent intent = new Intent(MainActivity.this, ActStartActivity.class);
startActivity(intent);

隐式Intent

1
2
3
4
5
6
7
Intent itt = new Intent();
itt.setAction(Intent.ACTION_DIAL);
// 声明一个拨号的URI
Uri uri = Uri.parse("tel:" + PHONE_NUMBER);
itt.setData(uri);
startActivity(itt);
break;

Intent传递消息

向下传递

1
2
3
4
5
6
7
8
9
10
11
// 传递数据
Intent itt = new Intent(this, ActStartActivity.class);
itt.putExtra("main_msg", "这是一条来自Main的消息");
startActivity(itt);
// 接收数据
Intent itt = getIntent();
if(itt != null && itt.hasExtra("main_msg")) {
String msg = itt.getStringExtra("main_msg");
TextView tv = findViewById(R.id.receiver);
tv.setText(msg);
}

向上传递
不想写了,略了

广播机制

广播分为:系统广播、用户自定义广播
使用步骤:

  1. 定义广播接收器
    1
    2
    3
    4
    5
    6
    7
    public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    // 在这里处理接收到的广播消息
    }
    }

  2. 注册广播接收器
    a. 静态注册
    1
    2
    3
    MyBroadcastReceiver receiver = new MyBroadcastReceiver();
    IntentFilter filter = new IntentFilter("com.example. MY_ACTION");
    context.registerReceiver(receiver, filter);
    b. 动态注册
    1
    2
    3
    4
    5
    <receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
    <action android:name="com.example.MY_ACTION" />
    </intent-filter>
    </receiver>
  3. 创建广播消息
    1
    2
    Intent broadcastIntent = new Intent("com.example.MY_ACTION");
    broadcastIntent.putExtra("extra_key", "extra_value"); // 可选:添加额外的数据
  4. 发送广播
    1
    context.sendBroadcast(broadcastIntent);

Service

当用户播放音乐时,可以使用Service来实现后台音乐播放的功能。以下是一个简单的示例:

  1. 创建一个MusicService类,该类继承自Service,并在其中实现音乐播放逻辑。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    public class MusicService extends Service {
    private MediaPlayer mediaPlayer;

    @Override
    public void onCreate() {
    super.onCreate();
    // 初始化MediaPlayer等操作
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    // 处理从Activity传递过来的播放控制指令
    String action = intent.getAction();
    if (action.equals("play")) {
    playMusic();
    } else if (action.equals("pause")) {
    pauseMusic();
    } else if (action.equals("stop")) {
    stopMusic();
    }
    return START_STICKY;
    }

    private void playMusic() {
    // 播放音乐的逻辑
    }

    private void pauseMusic() {
    // 暂停音乐的逻辑
    }

    private void stopMusic() {
    // 停止音乐的逻辑
    }

    @Override
    public IBinder onBind(Intent intent) {
    return null;
    }
    }
  2. 在AndroidManifest.xml文件中声明MusicService。

    1
    <service android:name=".MusicService" />
  3. 在Activity中通过Intent启动和控制音乐播放。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // 启动音乐播放服务
    Intent intent = new Intent(this, MusicService.class);
    startService(intent);

    // 发送播放指令
    Intent playIntent = new Intent(this, MusicService.class);
    playIntent.setAction("play");
    startService(playIntent);

    // 发送暂停指令
    Intent pauseIntent = new Intent(this, MusicService.class);
    pauseIntent.setAction("pause");
    startService(pauseIntent);

    // 发送停止指令
    Intent stopIntent = new Intent(this, MusicService.class);
    stopIntent.setAction("stop");
    startService(stopIntent);

通过上述示例,您可以创建一个Service来处理音乐播放的逻辑,并通过启动服务和发送指令的方式控制音乐的播放、暂停和停止。即使在用户切换到其他应用程序或锁定屏幕时,音乐播放服务仍可在后台持续运行。

如果您希望通过广播与Service进行交互,可以使用以下步骤:

  1. 定义广播接收器类:创建一个继承自BroadcastReceiver的广播接收器类,用于接收来自Activity或其他组件发送的广播消息。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class MusicControlReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    // 在这里处理接收到的广播消息
    String action = intent.getAction();
    if (action.equals("play")) {
    // 处理播放音乐的逻辑
    } else if (action.equals("pause")) {
    // 处理暂停音乐的逻辑
    } else if (action.equals("stop")) {
    // 处理停止音乐的逻辑
    }
    }
    }
  2. 注册广播接收器:在Service的onCreate()方法中注册广播接收器,以便Service能够接收广播消息。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class MusicService extends Service {
    private MusicControlReceiver receiver;

    @Override
    public void onCreate() {
    super.onCreate();
    // 初始化操作和其他逻辑
    receiver = new MusicControlReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction("play");
    filter.addAction("pause");
    filter.addAction("stop");
    registerReceiver(receiver, filter);
    }

    // ... 其他方法和逻辑 ...

    @Override
    public void onDestroy() {
    super.onDestroy();
    // 在Service销毁时注销广播接收器
    unregisterReceiver(receiver);
    }
    }
  3. 在Activity中发送广播消息:在需要控制音乐播放的地方,发送相应的广播消息给Service。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 发送播放指令
    Intent playIntent = new Intent("play");
    sendBroadcast(playIntent);

    // 发送暂停指令
    Intent pauseIntent = new Intent("pause");
    sendBroadcast(pauseIntent);

    // 发送停止指令
    Intent stopIntent = new Intent("stop");
    sendBroadcast(stopIntent);

通过上述步骤,您可以通过广播消息在Activity和Service之间进行交互。当Activity发送广播消息时,Service的广播接收器将接收到相应的消息并执行相应的操作,以控制音乐播放。这种方式可以实现跨组件的通信和控制。