Android ·移动应用开发 创建第一个Android项目

文章目录

  • 一、创建第一个Android项目
    • 1.1 准备好Android Studio
    • 1.2 运行程序
    • 1.3 程序结构是什么
      • app下的结构
        • res - 子目录(所有图片、布局、字符串等资源)
        • AndroidManifest.xml 有四大组件,程序添加权限声明
      • Project下的结构
  • 二、开发android时,部分库下载异常慢
    • 2.1 项目中更换下载仓库
    • 2.2 离线模式配置 Gradle
  • 三、Kotlin代码(本篇Android项目不会涉及用kotlin创建文件,先介绍后续再涉及)
    • 3.1 变量
    • 3.2 函数
    • 3.3 条件控制
      • 3.3.1 if条件语句
      • 3.3.2 when条件语句
    • 3.4 for-in循环
        • 使用step跳过区间内的元素
        • 可以使用`until`关键字来创建一个左闭右开的区间,
        • downTo遍历降序区间
    • 3.5 面向对象编程
      • 3.5.1 继承
        • 同样的我们也可以继承于Java
        • Open 继承
        • 我们观察一下用Java和Kotlin分别创建的安卓项目的主活动
  • 四、活动(本篇以Java代码,先行介绍)
    • 4.1 创建活动
      • 4.1.1 Android Studio 会自动在AndroidManifest文件中注册
      • 4.1.2 活动中使用Toast
        • 写法
        • LENGTH_SHORT=0
        • LENGTH_LONG = 1
      • 4.1.3 销毁活动
    • 4.2 Intent 跨越活动
      • 4.2.1 显示的Intent
      • 4.2.2 隐式Intent
        • 我们还可以跳转到其他地方,如网页(这和我们平时的app如出一辙)
      • 4.2.3Action 和 Category
      • 4.2.4 传递给下一个活动数据
        • (1)发送活动方
        • (2)接受活动方
        • (3)打开日志Logcat
      • 4.2.5 返回数据给上一个活动
        • (1)副活动中
        • (2)主活动
    • 4.3 安卓 Activity生命周期
      • 4.3.1 概述
      • 4.3.2 过程
        • (1)创建活动,并简单的xml配个botton
        • (2)主活动
        • (3)启动虚拟机,看日志Logcat
    • 4.4 活动被回收了怎么办(GPT)
      • 4.4.1. 保存和恢复数据
      • 4.4.2. 使用ViewModel
      • 4.4.3. 持久化数据
      • 4.4.4. 处理返回结果
    • 4.5 启动模式

一、创建第一个Android项目

1.1 准备好Android Studio

在这里插入图片描述
选择
在这里插入图片描述
写信息
在这里插入图片描述
等待构建Gradle
在这里插入图片描述

可以选择我们的模拟器,甚至我们可以通过手机屏幕共享的方式,把手机的开发者模式打开等操作,下载到本机手机之中,可以0距离的感受,程序之美。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2 运行程序

在这里插入图片描述

1.3 程序结构是什么

app下的结构

这种的结构化的项目简洁明了,提高开发效率和代码质量
在这里插入图片描述
build - 编译时自动生成的文件
libs - 第三方jar包放在libs目录下
java - 放置所需Java 代码,自动生成了一个MainActivity 文件

res - 子目录(所有图片、布局、字符串等资源)

我们应该创建不同分辨率的目录,如drawable-hdpi、drawable-xhdpi、drawable-xxhdpi等,并在制作程序时提供几个不同分辨率的版本,是为了适应不同设备的屏幕密度和分辨率
在这里插入图片描述
打开我们的子目录
在这里插入图片描述
这里面就是我们配置的字符串,调用使用,不用全局在中出现相同的多次构建
在这里插入图片描述
怎么构建
在XML中通过@string/app_name可以获得该字符串的引用。
在这里插入图片描述
最终
在这里插入图片描述
点击可以替换
在这里插入图片描述

AndroidManifest.xml 有四大组件,程序添加权限声明

在这里插入图片描述
MainActivity
在这里插入图片描述
res/layout 目录下的activity_main.xml
在这里插入图片描述

Project下的结构

在这里插入图片描述

  1. .gradle 文件夹:包含Gradle构建系统生成的缓存文件和临时文件。

  2. .idea 文件夹:包含项目相关的IDE配置文件,如编译器设置、运行配置等。

  3. app 文件夹:是Android应用程序的主要代码和资源目录。

  4.  - java 文件夹:包含Java源代码文件。- res 文件夹:包含应用程序所需的资源文件,如布局文件、图像文件、字符串等。- AndroidManifest.xml 文件:包含应用程序的清单文件,定义了应用程序的基本信息、权限、组件、界面等。
    
    • test 文件夹:包含单元测试的源代码和资源文件。

    • androidTest 文件夹:包含Android测试的源代码和资源文件。

    • build.gradle 文件:定义了应用程序的构建配置,包括依赖项、版本号等。

    • proguard-rules.pro 文件:定义了混淆规则,用于在发布时压缩、优化和混淆应用程序的代码。

  5. build 文件夹:包含构建生成的输出文件,如APK文件、中间文件等。

  6. gradle 文件夹:包含Gradle构建系统的配置文件和插件。

    • wrapper 文件夹:包含Gradle的包装器文件,用于自动下载和管理Gradle的版本。

    • .gitignore 版本控制

    • build.gradle 文件:定义了项目级别的构建配置,如Gradle版本、插件等。

    • gradle.properties 文件:包含Gradle属性的配置文件。

    • gradlew 和 gradlew.bat 文件:Gradle的命令行构建脚本,可在命令行界面中使用。

  7. settings.gradle 文件:定义了项目的模块和构建设置。
    这是Android Studio项目的基本目录结构,其中最重要的部分是app 文件夹,它包含了应用程序的源代码和资源文件。其他文件夹和文件用于项目的构建和配置。

二、开发android时,部分库下载异常慢

2.1 项目中更换下载仓库

maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/google/' }
maven { url 'https://maven.aliyun.com/repository/jcenter/' }
maven { url 'https://maven.aliyun.com/repository/central/' }

在这里插入图片描述

2.2 离线模式配置 Gradle

将 Gradle.zip 解压到 “C:\User\你的用户名.gradle\wrapper\dists” 下,最终路径为: “C:\User\你的用户名.gradle\wrapper\dists\gradle-7.4-bin” 和 “C:\User\你的用户名.gradle\wrapper\dists\gradle-8.0-bin”

三、Kotlin代码(本篇Android项目不会涉及用kotlin创建文件,先介绍后续再涉及)

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

3.1 变量

使用val(value 的简写)声明一个变量时,该变量被视为不可变的,即在初始赋值之后无法重新赋值。这类似于Java中的final变量。

使用var(variable 的简写)声明一个变量时,该变量被视为可变的,即在初始赋值之后仍然可以重新赋值。这类似于Java中的非final变量。

Kotlin 中没有基础数据类型,只有封装的数字类型,你每定义的一个变量,其实 Kotlin 帮你封装了一个对象,这样可以保证不会出现空指针。

# 显式地声明了变量a为Int类型
val a: Int = 10 

在这里插入图片描述

3.2 函数

参数的声明格式是“参数名: 参数类型”,其中参数名也是可以随便定义的

fun main() {println(fun1(1, 2))
}
fun fun1(num1:Int,num2: Int):Int{return num1+num2
}

3.3 条件控制

3.3.1 if条件语句

var value = 0 
if (num1 > num2) {
value = num1} else {
value = num2} 

Kotlin中的if语句相比于Java 有一个额外的功能,它是可以有返回值的

val result = if (条件表达式) {// 如果条件为真,则返回这里的值
} else {// 如果条件为假,则返回这里的值
}

例子

fun fun1(num1: Int, num2: Int): Int {return if (num1 > num2) {
num1} else {
num2}
} 
fun fun1(num1: Int, num2: Int) = if (num1 > num2) {num1
} else {num2
} 

再次

val max = if (a > b) a else b
fun fun1(num1: Int, num2: Int)= if (num1 > num2) num1 else num2

3.3.2 when条件语句

这种直通式

匹配值 -> { 执行逻辑 } 
when (条件表达式) {1 -> {// 如果条件匹配值1,则执行这里的代码块}2 -> {// 如果条件匹配值2,则执行这里的代码块}else -> {// 如果条件都不匹配,则执行这里的代码块}
}
is关键字就是类型匹配的核心,相当于Java 中的instanceof关键字。

when (num) {
is Int -> println("number is Int")
is Double -> println("number is Double")
else -> println("number not support")}

3.4 for-in循环

kotlin的while和Java 中的while循环没有任何区别

fun main() {val range = 0..10for (i in range step 2) {println(i)}
}
使用step跳过区间内的元素

在这里插入图片描述

可以使用until关键字来创建一个左闭右开的区间,

在这里插入图片描述

downTo遍历降序区间

在这里插入图片描述

3.5 面向对象编程

class Person {var name: String = ""var age=0fun show(){println("Name: $name, Age: $age")println(name +"is" + age + " years old.")}
}fun main() {val p = Person()p.name = "Alice"p.age = 30p.show() // Output: Name: Alice, Age: 30
}

第一个打印语句使用了字符串模板( n a m e 和 name和 nameage),将属性name和age的值插入到输出语句中,打印出"Name: Alice, Age: 30"。

第二个打印语句使用了字符串拼接(name +“is” + age + " years old.“),将属性name、字符串"is”、属性age和字符串" years old.“拼接在一起,打印出"Alice is 30 years old.”。

3.5.1 继承

在Person类的前面加上open关键字就可以了
要让Student类继承Person类

在Java 中继承的关键字是extends,而在Kotlin中是一个冒号

open class Person {var name: String = ""var age=0fun show(){println("Name: $name, Age: $age")println(name +"is" + age + " years old.")}
}
class Student :Person(){var grade:Int=0fun shows(){println("Name: $name, Age: $age, Grade: $grade")}}
fun main() {val s=Student()s.name="Bob"s.age=20s.grade=3s.shows() //Output: Name: Bob, Age: 20, Grade: 3
}
同样的我们也可以继承于Java

在这里插入图片描述
java

public class cc {private String name;private  int age;public cc() {}public cc(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

kotlin

class Student : cc() {var grade: Int = 0fun shows() {println("Name: $name, Age: $age, Grade: $grade")}}fun main() {val s = Student()s.name = "Bob"s.age = 20s.grade = 3s.shows() //Output: Name: Bob, Age: 20, Grade: 3
}
Open 继承
如果你希望在 Kotlin 中继承某个 Java 类,需要手动在 Kotlin 代码中为该类添加 open 修饰符,以明确表明该类是可继承的。
如果一个类不是专门为继承而设计的,那么就应该主动将它加上final声明,禁止它可以被继承。

在 Kotlin 中,默认情况下,所有类都是 final 的,即它们不能被继承。相比之下,Java 中的类默认是可以被继承的,除非使用了 final 关键字显式地禁止继承。

当你在 Kotlin 中继承一个 Java 类时,Kotlin 并不会隐式地为 Java 类添加 open 修饰符。这是因为 Kotlin 不会假设 Java 类的设计者希望允许继承,因此需要在 Kotlin 中显式地使用 open 关键字来指示类是可继承的。

我们观察一下用Java和Kotlin分别创建的安卓项目的主活动
Kotlin

在这里插入图片描述

Java

在这里插入图片描述

四、活动(本篇以Java代码,先行介绍)

活动是安卓应用的主要组件之一,安卓中的活动(Activity)是指用户交互界面的一部分,它通常对应应用程序中的一个屏幕。

通过管理活动的生命周期(创建、启动、恢复、暂停、停止和销毁),我们作为开发者可以控制活动的状态和行为。

活动之间可以通过意图(Intent)进行跳转和通信。

把各种控件和视图,按钮、文本框、图像等联系起来,启动其他活动或从其他活动返回,用户可以在不同的界面之间进行切换和交互。

总之,活动作为安卓应用程序的一个重要组件,负责用户界面的展示和交互处理,使得用户可以与应用程序进行互动。

4.1 创建活动

在com.example.hellowolrd包下 ->New ->Activity ->Empty Activity
在这里插入图片描述
我们的两个活动:
在这里插入图片描述

4.1.1 Android Studio 会自动在AndroidManifest文件中注册

我们打开app/src/main/AndroidManifest.xml文件代码如下所示:
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools" ><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"tools:targetApi="31" ><activityandroid:name=".OtherActivity"android:exported="false" /><activityandroid:name=".MainActivity"android:exported="true" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

4.1.2 活动中使用Toast

Toast会在屏幕上显示一段时间,用于在应用程序的界面上显示一条简短的消息,然后自动消失。

写法
// 要显示的消息文本
String message = "Hello, Toast!";
// 创建并显示Toast
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();

当调用makeText()方法,并通过链式调用show()方法来创建并显示Toast。getApplicationContext()是一种获取当前活动上下文的方法,可以在活动中使用。

需要注意的是,Toast的 makeText()方法返回的是一个Toast对象,可以通过调用show()方法来显示。

在调用show()方法后,Toast会在屏幕上显示一段时间,然后自动消失。

Java
在这里插入图片描述

Kotlin
在这里插入图片描述

val button1: Button = findViewById(R.id.button12)
button1.setOnClickListener {Toast.makeText(this, "Yes", Toast.LENGTH_LONG).show() }
LENGTH_SHORT=0

Android 短时间的Toast

LENGTH_LONG = 1

Android 长时间的Toast

4.1.3 销毁活动

Activity类提供了一个finish()

延迟销毁

package com.example.myapplication;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;public class OtherActivity extends AppCompatActivity {private Button button1;private Handler handler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_other);button1 = findViewById(R.id.button1);button1.setOnClickListener(v -> {Toast.makeText(this, "TestOther", Toast.LENGTH_SHORT).show();handler.postDelayed(() -> finish(), 2000);});}
}

finishmp4

4.2 Intent 跨越活动

4.2.1 显示的Intent

先创建一个新的活动,并在其绑定创建的layout文件之中简单的放置一个按钮,目的是在跳转的时候直观的有明显的体验

package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;import android.view.View;
import android.widget.Button;
import android.widget.Toast;public class OtherActivity extends AppCompatActivity {private Button button1;private Handler handler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_other);button1 = findViewById(R.id.button1);button1.setOnClickListener(v -> {Toast.makeText(this, "TestOther", Toast.LENGTH_SHORT).show();Intent intent = new Intent(OtherActivity.this, SecondActivity.class);// 在延迟2秒后执行 finish() 和 startActivity()handler.postDelayed(() -> {finish();startActivity(intent);}, 2000);});}
}

Intent跳转其他活动

4.2.2 隐式Intent

我们在当前文件在指定出来我们可以转向的动作名称
在这里插入图片描述

button1.setOnClickListener(v -> {Toast.makeText(this, "TestOther", Toast.LENGTH_SHORT).show();Intent intent = new Intent("x111");startActivity(intent);});
我们还可以跳转到其他地方,如网页(这和我们平时的app如出一辙)
button1.setOnClickListener(v-> {Intent intent =new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://www.baidu.com"));startActivity(intent);});

点击按钮后,创建了一个意图(Intent)并设置了其动作(Action)为Intent.ACTION_VIEW,同时指定了要查看的数据是一个URL,即http://www.baidu.com。系统收到这个意图后,会识别出这是一个网页链接,并自动使用默认的Web浏览器打开百度网站页面。同样地,如果intent指向的是一个电话号码或者一个本地文件(如图片、视频等),则相应程序(拨号器或媒体播放器等)会被唤起以处理这些数据。
在这里插入图片描述
在这里插入图片描述

4.2.3Action 和 Category

在Android中,Action 和 Category 是 Intent 的重要组成部分,它们用于定义和过滤应用程序间交互的行为意图(Intent)。

Action 描述了Intent的主要动作或目的。例如,发送一个电子邮件可以使用 ACTION_SEND 动作;打开网页可以使用 ACTION_VIEW 动作等。

Category 为Intent添加了额外的上下文信息,进一步描述了Intent的应用场景或意图所属的类别
在这里插入图片描述
一个Intent不仅需要定义一个动作(如ACTION_MAIN),还需要至少一个类别(如CATEGORY_LAUNCHER),这样才能准确地匹配到相应的组件并触发相应的行为。在AndroidManifest.xml文件中,开发者会在 标签内为Activity声明它可以响应哪些动作和类别组合。

4.2.4 传递给下一个活动数据

(1)发送活动方
//  传递给下一个活动数据
button1.setOnClickListener(v -> {String data = "你会魔法吗✧(≖ ◡ ≖✿)";Intent intent = new Intent(OtherActivity.this, SecondActivity.class);intent.putExtra("exdata", data);startActivity(intent);
});
(2)接受活动方
 @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);Intent intent =getIntent();String data =intent.getStringExtra("exdata");Log.d("Sec",data);}
(3)打开日志Logcat

在这里插入图片描述

4.2.5 返回数据给上一个活动

在这里插入图片描述

(1)副活动中
  @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);Intent intent =getIntent();String data =intent.getStringExtra("exdata");Log.d("Sec",data);Button buttonxx=findViewById(R.id.buttonxx);buttonxx.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent =new Intent();intent.putExtra("resdata","hello_你会魔法吗✧(≖ ◡ ≖✿)");setResult(RESULT_OK,intent);finish();}});}
(2)主活动
//  传递给下一个活动数据
button1.setOnClickListener(v -> {String data = "你会魔法吗✧(≖ ◡ ≖✿)";Intent intent = new Intent(OtherActivity.this, SecondActivity.class);intent.putExtra("exdata", data);startActivityForResult(intent,1);
});

注意 startActivityForResult方法重写

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == 1 && resultCode == RESULT_OK) {String reData = data.getStringExtra("resdata");// 在这里处理接收到的数据 reDataLog.d("OtherActivity", reData);}
}

4.3 安卓 Activity生命周期

4.3.1 概述

在这里插入图片描述

Android Activity生命周期的各个状态及其转换关系
在这里插入图片描述

  1. 创建阶段

    • onCreate(Bundle savedInstanceState): 活动第一次被创建时调用,进行初始化工作。
    • onStart(): 表示活动正在启动,即将变为可见状态。
    • onResume(): 活动已开始与用户交互,并处于运行状态。
  2. 运行阶段

    • onResume()之后,Activity处于运行状态。
  3. 暂停阶段

    • onPause(): 当有新的Activity启动并覆盖当前Activity或当前Activity不再位于前台时调用。
  4. 停止阶段

    • onStop(): 当Activity完全不可见时调用。
  5. 恢复/重启阶段

    • onRestart(): 如果Activity之前被停止而现在重新回到前台,会先调用此方法,然后经历onStart()onResume()
  6. 销毁阶段

    • onDestroy(): 在Activity被系统决定彻底销毁前调用,用于释放资源。
  7. 其他回调方法:

    • onSaveInstanceState(Bundle outState): 保存临时性数据以备在Activity重建时恢复。
    • onRestoreInstanceState(Bundle savedInstanceState): 用于还原之前保存的状态。

4.3.2 过程

注意如果我们启动的时候不是这个想要看的内容,可能和主启动活动有关

我们在在这里插入图片描述
修改
在这里插入图片描述

(1)创建活动,并简单的xml配个botton

在这里插入图片描述

(2)主活动
package com.example.myapplication;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;public class MainActivity extends AppCompatActivity {public static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button startNormalActivity = findViewById(R.id.ShowActivity);Button startDialogActivity = findViewById(R.id.ShowActivity2);startNormalActivity.setOnClickListener(v -> {Intent intent = new Intent(MainActivity.this, ShowActivity.class);startActivity(intent);});startDialogActivity.setOnClickListener(v -> {Intent intent = new Intent(MainActivity.this, ShowActivity2.class);startActivity(intent);});}@Overrideprotected void onStart() {super.onStart();Log.d(TAG, "onStart");}@Overrideprotected void onResume() {super.onResume();Log.d(TAG, "onResume");}@Overrideprotected void onPause() {super.onPause();Log.d(TAG, "onPause");}@Overrideprotected void onStop() {super.onStop();Log.d(TAG, "onStop");}@Overrideprotected void onDestroy() {super.onDestroy();Log.d(TAG, "onDestroy");}@Overrideprotected void onRestart() {super.onRestart();Log.d(TAG, "onRestart");}
}
(3)启动虚拟机,看日志Logcat

我们需要点击任意一个按钮,并回退(返回键)
观察日志的内容
在这里插入图片描述

4.4 活动被回收了怎么办(GPT)

Android Activity 回收与恢复策略

在Android中,当系统资源紧张时,Activity可能会因内存不足而被回收(destroy)。为应对这种情况并确保应用能够正确恢复用户界面和数据,可以采用以下几种方法:

4.4.1. 保存和恢复数据

onSaveInstanceState(Bundle outState)方法中保存关键数据,以便在Activity重新创建时通过onCreate(Bundle savedInstanceState)onRestoreInstanceState(Bundle savedInstanceState)恢复这些数据。

   @Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);// 保存数据到BundleoutState.putInt("key", someImportantValue);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if (savedInstanceState != null) {// 恢复数据int importantValue = savedInstanceState.getInt("key");// 使用恢复的数据...}}

4.4.2. 使用ViewModel

借助Android架构组件中的ViewModel类,可以在配置更改或Activity生命周期变化时保持UI相关数据的持久性。即使Activity被销毁,ViewModel中的数据也能保留下来。

   public class MyViewModel extends ViewModel {private MutableLiveData<Integer> someLiveData;public MutableLiveData<Integer> getSomeLiveData() {if (someLiveData == null) {someLiveData = new MutableLiveData<>();// 初始化数据...}return someLiveData;}}public class MainActivity extends AppCompatActivity {private MyViewModel viewModel;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);viewModel = new ViewModelProvider(this).get(MyViewModel.class);viewModel.getSomeLiveData().observe(this, value -> {// 更新UI...});}}

4.4.3. 持久化数据

对于需要长期保存的重要数据,可将其持久化至数据库、SharedPreferences或其他文件存储中。

4.4.4. 处理返回结果

如果Activity是通过startActivityForResult启动的,则需在onActivityResult中处理结果,即便Activity在获取结果前被销毁过。

4.5 启动模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/468878.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【日常聊聊】新年新征程:迎接学习的挑战

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 结语 我的其他博客 前言 随着新的一年的到来&#xff0c;程序员们站在了全新的起点。这是一个充满机遇和挑战的时刻&#xff0…

Hive的Join连接、谓词下推

前言 Hive-3.1.2版本支持6种join语法。分别是&#xff1a;inner join&#xff08;内连接&#xff09;、left join&#xff08;左连接&#xff09;、right join&#xff08;右连接&#xff09;、full outer join&#xff08;全外连接&#xff09;、left semi join&#xff08;左…

寒假 day13

1.请编程实现二维数组的杨慧三角 #include<stdio.h> #include<string.h> int main(int argc, const char *argv[]) { int n,i,j;printf("please enter n:");scanf("%d",&n);int arr[n][n];for(i0;i<n;i){for(j0;j<i;j){if(j0 || ij…

红队打靶练习:Alfa:1

下载连接点击此处即可&#xff01; 目录 信息收集 1、arp 2、nmap 3、gobuster WEB web信息收集 FTP登录 smaba服务 crunch密码生成 提权 系统信息收集 权限提升 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, …

设计模式3-责任链模式

责任链模式是一种行为设计模式&#xff0c;它允许你创建一个对象链。请求沿着这条链传递&#xff0c;直到有一个对象处理它为止。这种模式通常用于需要以某种方式动态地决定处理请求的顺序或方式的情况。 类图&#xff1a; 从图中可见最大的特点是AbstractHandler它自己聚合了自…

SAP MM学习笔记42 - 特殊调达流程 - 受托品(寄售)

上一章讲了 外注加工的知识。 详细可以参考如下链接。 SAP MM学习笔记41 - 特殊调达流程 - 外注加工-CSDN博客 咱们继续学习特殊调达流程。 本章主要讲受托品。 1&#xff0c;什么是受托品 &#xff08;寄售&#xff09; 仕入先提供的商品&#xff0c;商品是放在你公司了&a…

【十八】【C++】deque双端队列简单使用和deque底层实现探究(部分代码)

deque简单使用 在C中&#xff0c;双端队列&#xff08;Double-Ended Queue, deque&#xff09;是一种具有动态大小的序列容器&#xff0c;允许在两端快速插入和删除元素。与std::vector相比&#xff0c;std::deque提供了更加灵活的数据结构&#xff0c;特别是在需要频繁在序列…

Swift Combine 有序的异步操作 从入门到精通十二

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

bugku 2

社工-初步收集 购买辅助--下载辅助 得到一个zip文件 里面有exe 不知道有啥用 先用dirsearch扫一下 找到/admin/login.php 随便用了个弱口令登录失败 后面看了要用wireshrak抓包 找到邮箱和pass 把pass解码 本来以为后台直接登录 但是登录失败 就是要用邮箱登录 找到账…

Vue学习笔记(三)常用指令、生命周期

Vue学习笔记&#xff08;三&#xff09;常用指令 vue指令&#xff1a;html标签上带有 v- 前缀的特殊属性&#xff0c;不同的指令具有不同的含义&#xff0c;可以实现不同的功能。 常用指令&#xff1a; 指令作用v-for列表渲染&#xff0c;遍历容器的元素或者对象的属性v-bind…

Vegeta压测工具学习与使用

Vegeta压测工具学习与使用 目标&#xff1a; 能够在命令行下使用Vegeta对指定API进行测试了解如何导出结果&#xff0c;以及能获得什么样的结果(P99,P99.9,QPS)探索能否导出其他结果&#xff0c;是否能够执行复杂命令或简易脚本等 时间比较紧迫&#xff0c;预计两到三个小时内完…

UnityShader——03图形硬件简史与可编程管线

图形硬件简史与可编程管线 GPU发展简史 GPU英文全称Graphic Processing Unit&#xff0c;中文翻译为“图形处理器”&#xff0c;在现代计算机系统中的作用变得越来越重要 20世纪六七十年代&#xff0c;受硬件条件的限制&#xff0c;图形显示器只是计算机输出的一种工具&…