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.mzph.cn/news/682718.shtml

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

相关文章

【ArcGIS Pro二次开发】(79):符号系统_CIMUniqueValueRenderer

CIMUniqueValueRenderer是ArcGIS Pro SDK中的一个类&#xff0c;用于创建唯一值渲染器&#xff08;Unique Value Renderer&#xff09;。 在ArcGIS Pro中长这样&#xff1a; 通过对CIMUniqueValueRenderer的操作&#xff0c;可以对符号系统进行更改&#xff0c;实现很多功能。…

尚硅谷最新Node.js 学习笔记(一)

目录 一、Nodejs入门 1.1、为什么要学习Nodejs&#xff1f; 1.2、Nodejs是什么&#xff1f; 1.3、Nodejs的作用 1.4、Nodejs安装 1.5、Nodejs初体验 1.6、编码注意事项 二、Buffer&#xff08;缓冲器&#xff09; 2.1、概念 2.2、特点 2.3、使用 创建Buffer Buffe…

Cocos2dx-lua ScrollView[一]基础篇

一.ScrollView概述 cocos游戏中ScrollView控件大量使用,95%以上的项目都会使用ScrollView,个别游戏可能全部使用翻页的滑动效果。如果想要精通Cocos的UI开发,精通ScrollView控件非常关键,因此对ScrollView的使用进行总结很有必要。 下文缩写说明:sv = ScrollView, item代…

嵌入式Linux网络编程入门:轻松构建网络通信

大家好&#xff0c;今天给大家介绍嵌入式Linux网络编程入门&#xff1a;轻松构建网络通信&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 为什么选择嵌入式Linux网络编程&#x…

vue3+ts+vite+uniapp项目常见问题

vue3tsvite中""路径失效的问题 ""需要进行配置&#xff1a; 首先npm install types/node --save-dev&#xff08;需要用到node其中的path&#xff09;接着在vite.config.ts配置文件中进行配置&#xff1a; 引入 import path from ‘path’&#xff0c;然…

Imgui(2) | macOS 绘制 CPU 占用率曲线

Imgui(2) | macOS 绘制 CPU 占用率曲线 文章目录 Imgui(2) | macOS 绘制 CPU 占用率曲线0. 简介1. 绘制曲线 - 以正弦函数为例1.1 基于 sf::RectangleShape 的渲染 - 不好看&#xff0c;效率低1.2 基于 sf::VertexArray 的绘制 2. 获取和绘制所有 CPU 的占用率2.1 测试程序 - 用…

LeetCode Python - 16.最接近的三数之和

目录 题目答案运行结果 题目 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1&#xff1a; 输入&#xff1a;nums [-1,2,1,-4],…

基于轻量级卷积神经网络模型MobileNet开发构建基于GTSRB数据集的道路交通标识识别系统

相信经常需要开车出行的人对于各种各样的道路交通标识定是不陌生的&#xff0c;但是对于经常不开车的人来说生活中出现的形形色色的道路交通标识就未必都能认出来了&#xff0c;本文的主要目的就是想要基于CNN来开发构建道路交通标识识别分析系统&#xff0c;实现看图识标&…

谷歌浏览器安装扩展程序axure-chrome-extension

注&#xff1a; 文末附扩展附件&#xff1a;axure-chrome-extension_v0.7.0.crx 1、安装扩展程序axure-chrome-extension 找到axure-chrome-extension.crx&#xff0c;把axure-chrome-extension.crx后缀改为zip&#xff0c;然后解压&#xff0c;得到一个文件夹 2、打开谷歌浏览…

枚举知识点解析

枚举是什么&#xff1f;枚举就是列举&#xff0c; 将东西一一列举出来。 生活中有许多地方需要用到枚举&#xff0c; 比如一年有12个月&#xff0c;一星期有7天&#xff0c; 这些都需要进行枚举。 那么&#xff0c; 如何进行枚举的定义呢&#xff1f; 如下 枚举中的值是一种…

ubuntu22.04@laptop OpenCV Get Started: 008_image_filtering_using_convolution

ubuntu22.04laptop OpenCV Get Started: 008_image_filtering_using_convolution 1. 源由2. convolution应用Demo2.1 C应用Demo2.2 Python应用Demo 3. 重点分析3.1 identity矩阵3.2 all ones 5x5矩阵3.3 blur 5x5矩阵3.4 GaussianBlur 5x5矩阵3.5 medianBlur 5x5矩阵3.6 Sharpe…

Spring 用法学习总结(一)之基于 XML 注入属性

百度网盘&#xff1a; &#x1f449; Spring学习书籍链接 Spring学习 1 Spring框架概述2 Spring容器3 基于XML方式创建对象4 基于XML方式注入属性4.1 通过set方法注入属性4.2 通过构造器注入属性4.3 使用p命名空间注入属性4.4 注入bean与自动装配4.5 注入集合4.6 注入外部属性…

C# Winform .net6自绘的圆形进度条

using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms;namespace Net6_GeneralUiWinFrm {public class CircularProgressBar : Control{private int progress 0;private int borderWidth 20; // 增加的边框宽度public int Progr…

CTFshow web(php文件上传155-158)

web155 老样子&#xff0c;还是那个后端检测。 知识点&#xff1a; auto_append_file 是 PHP 配置选项之一&#xff0c;在 PHP 脚本执行结束后自动追加执行指定的文件。 当 auto_append_file 配置被设置为一个文件路径时&#xff0c;PHP 将在执行完脚本文件的所有代码后&…

探索IDE的世界:什么是IDE?以及适合新手的IDE推荐

引言 在编程的世界里&#xff0c;集成开发环境&#xff08;IDE&#xff09;是我们日常工作的重要工具。无论是初学者还是经验丰富的开发者&#xff0c;一个好的IDE都能极大地提高我们的编程效率。那么&#xff0c;什么是IDE呢&#xff1f;对于新手来说&#xff0c;又应该选择哪…

OpenGL-ES 学习(2)---- DepthTest

深度测试 OpenGL-ES 深度测试是指在片段着色器执行之后&#xff0c;利用深度缓冲区所保存的深度值决定当前片段是否被丢弃的过程 深度缓冲区通常和颜色缓冲区有着相同的宽度和高度&#xff0c;一般由窗口系统自动创建并将其深度值存储为 16、 24 或 32 位浮点数。(注意只保存…

红队笔记Day3-->隧道上线不出网机器

昨天讲了通过代理的形式&#xff08;端口转发&#xff09;实现了上线不出网的机器&#xff0c;那么今天就来讲一下如何通过隧道上线不出网机器 目录 1.网络拓扑 2.开始做隧道&#xff1f;No&#xff01;&#xff01;&#xff01; 3.icmp隧道 4.HTTP隧道 5.SSH隧道 1.什么…

HarmonyOS鸿蒙学习基础篇 - 自定义组件(一)

前言 在ArkUI中&#xff0c;UI显示的内容均为组件&#xff0c;由框架直接提供的称为系统组件&#xff0c;由开发者定义的称为自定义组件。在进行 UI 界面开发时&#xff0c;通常不是简单的将系统组件进行组合使用&#xff0c;而是需要考虑代码可复用性、业务逻辑与UI分离&#…

【Linux】yum软件包管理器

目录 Linux 软件包管理器 yum 什么是软件包 Linux安装软件 查看软件包 关于rzsz Linux卸载软件 查看yum源 扩展yum源下载 Linux开发工具 vim编辑器 上述vim三种模式之间的切换总结&#xff1a; 命令模式下&#xff0c;一些命令&#xff1a; vim配置 Linux 软件包管理…

项目访问量激增该如何应对

✨✨ 欢迎大家来到喔的嘛呀的博客✨✨ &#x1f388;&#x1f388;希望这篇博客对大家能有帮助&#x1f388;&#x1f388; 目录 引言 一. 优化数据库 1.1 索引优化 1.2 查询优化 1.3 数据库设计优化 1.4 事务优化 1.5 硬件优化 1.6 数据库配置优化 二. 增加服务器资源…