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

news2024/11/29 20:40:42

文章目录

  • 一、创建第一个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..10
    for (i in range step 2) {
        println(i)
    }
}
使用step跳过区间内的元素

在这里插入图片描述

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

在这里插入图片描述

downTo遍历降序区间

在这里插入图片描述

3.5 面向对象编程

class Person {
    var name: String = ""
      var age=0

    fun show(){
        println("Name: $name, Age: $age")
        println(name +"is" + age + " years old.")

    }
}

fun main() {
    val p = Person()
    p.name = "Alice"
    p.age = 30
    p.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=0

    fun show(){
        println("Name: $name, Age: $age")
        println(name +"is" + age + " years old.")

    }
}
class Student :Person(){

    var grade:Int=0
    fun shows(){
        println("Name: $name, Age: $age, Grade: $grade")
         }

}
fun main() {
    val s=Student()
    s.name="Bob"
    s.age=20
    s.grade=3
    s.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 = 0

    fun shows() {
        println("Name: $name, Age: $age, Grade: $grade")
    }

}

fun main() {

    val s = Student()
    s.name = "Bob"
    s.age = 20
    s.grade = 3
    s.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" >

    <application
        android: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" >
        
        <activity
            android:name=".OtherActivity"
            android:exported="false" />
            
        <activity
            android: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();

    @Override
    protected 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();

    @Override
    protected 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)接受活动方
 @Override
    protected 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)副活动中
  @Override
    protected 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() {
            @Override
            public 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");
       // 在这里处理接收到的数据 reData
       Log.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";

    @Override
    protected 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);
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    @Override
    protected 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)恢复这些数据。

   @Override
   protected void onSaveInstanceState(Bundle outState) {
       super.onSaveInstanceState(outState);
       // 保存数据到Bundle
       outState.putInt("key", someImportantValue);
   }

   @Override
   protected 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;

       @Override
       protected 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.coloradmin.cn/o/1450050.html

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

相关文章

极市平台 | 16个图像分类方向开源数据集资源汇总(附下载链接,建议收藏!)

本文来源公众号“极市平台”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;16个图像分类方向开源数据集资源汇总&#xff08;附下载链接&#xff09; 本文汇总了16个图像分类相关的开源数据集&#xff0c;均附有下载链接。要构建…

苹果手机计算器怎么进行快速删除(退格)?

文章目录 前言方法 前言 总所周知&#xff0c;不论是学生、商人&#xff0c;还是工人&#xff0c;都必须使用计算器。其中&#xff0c;苹果手机的自带计算器&#xff0c;因为完美的环境&#xff0c;所以受到大多数人的喜爱&#xff0c;使用率极高。但是&#xff0c;苹果计算器…

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

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

Git快速掌握,通俗易懂

Git分布式版本控制工具 介绍 Git是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。Git是由Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。Git可以帮助开发者们管理代码的版本&#xff0c;避免代码冲突&#…

RabbitMQ配置消息转换器

1. 默认转换器 Test public void testSendMap() throws InterruptedException {// 准备消息Map<String, Object> msg new HashMap<>();msg.put("name", "harry");msg.put("age", 21);// 发送消息rabbitTemplate.convertAndSend(&q…

FreeRTOS知识点

1>任务调度算法 1.抢占式调度&#xff1a;高优先级的任务优先执行&#xff0c;并且可以打断低优先级的任务执行。 在FreeRTOSConfig.h中开启configUSE_PREEMPTION宏&#xff0c;将宏设置为1&#xff0c;关闭&#xff08;将宏设置为0&#xff09; 2.时间片轮转&#xff1a…

什么是 Flet?

什么是 Flet&#xff1f; Flet 是一个框架&#xff0c;允许使用您喜欢的语言构建交互式多用户 Web、桌面和移动应用程序&#xff0c;而无需前端开发经验。 您可以使用基于 Google 的 Flutter 的 Flet 控件为程序构建 UI。Flet 不只是“包装”Flutter 小部件&#xff0c;而是…

Repo命令使用实例(三十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

动态多目标优化算法基准测试问题JY

论文题目&#xff1a;Evolutionary Dynamic Multiobjective Optimization: Benchmarks and Algorithm Comparisons 进化动态多目标优化&#xff1a;基准测试和算法比较&#xff08;Shouyong Jiang and Shengxiang Yang, Senior Member, IEEE&#xff09;IEEE TRANSACTIONS ON …

【UE4】 通过按钮点击实现摄像机的切换 并通过鼠标控制新摄像机的旋转

效果 步骤 首先创建了4个Actor蓝图类 每个蓝图类内只拥有一个摄像机组件 将每个actor蓝图类摆放到场景的合适位置 在关卡蓝图中创建自定义事件&#xff0c;当该事件触发时切换摄像机 创建一个控件蓝图&#xff0c;在控件蓝图中创建如下5个按钮&#xff0c;并创建点击事件。按钮…

基于HTML5实现动态烟花秀效果(含音效和文字)实战

目录 前言 一、烟花秀效果功能分解 1、功能分解 2、界面分解 二、HTML功能实现 1、html界面设计 2、背景音乐和燃放触发 3、燃放控制 4、对联展示 5、脚本引用即文本展示 三、脚本调用及实现 1、烟花燃放 2、燃放响应 3、烟花canvas创建 4、燃放声音控制 5、实际…

SpringIOC之support模块ResourceBundleMessageSource

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

垃圾分类|城市垃圾分类管理系统|基于Springboot的城市垃圾分类管理系统设计与实现(源码+数据库+文档)

城市垃圾分类管理系统目录 目录 基于Springboot的城市垃圾分类管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、垃圾列表 2、公告信息管理 3、公告类型管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 …

php基础学习之运算符(重点在连接符和错误抑制符)

运算符总结 在各种编程语言中&#xff0c;常用的运算符号有这三大类&#xff1a; 算术运算符&#xff1a;&#xff0c;-&#xff0c;*&#xff0c;/&#xff0c;%位运算符&#xff1a;&&#xff0c;|&#xff0c;^&#xff0c;<<&#xff0c;>>赋值运算符&…

【深入理解DETR】DETR的原理与算法实现

1 DETR算法概述 ①端到端 ②Transformer-model 之前的方法都需要进行NMS操作去掉冗余的bounding box或者手工设计anchor&#xff0c; 这就需要了解先验知识&#xff0c;增加从超参数anchor的数量&#xff0c; 1.1 训练测试框架 一次从图像中预测n个object的类别 训练阶段我们…

数据结构——顺序表专题

目录 1. 数据结构的相关概念什么是数据结构为什么需要数据结构&#xff1f; 2. 顺序表顺序表的概念及结构顺序表分类静态顺序表动态顺序表 3. 动态顺序表的实现准备工作顺序表的初始化顺序表的扩容尾插头插尾删头删指定位置插入数据指定位置删除数据 4. 全部完整代码**test.c**…

构建智慧交通平台:架构设计与实现

随着城市交通的不断发展和智能化技术的迅速进步&#xff0c;智慧交通平台作为提升城市交通管理效率和水平的重要手段备受关注。本文将探讨如何设计和实现智慧交通平台的系统架构&#xff0c;以应对日益增长的城市交通需求&#xff0c;并提高交通管理的智能化水平。 ### 1. 智慧…

中小学信息学奥赛CSP-J认证 CCF非专业级别软件能力认证-入门组初赛模拟题第二套(阅读程序题)

CSP-J入门组初赛模拟题二 二、阅读程序题 (程序输入不超过数组或字符串定义的范围&#xff0c;判断题正确填√错误填X;除特殊说明外&#xff0c;判断题 1.5分&#xff0c;选择题3分&#xff0c;共计40分) 第一题 1 #include<bits/stdc.h> 2 using namespace std; 3 i…

算法——数论——快速幂

目录 快速幂 费马小定理 一、试题 算法训练 A的B的C次方次方 快速幂 快速幂是一种用于快速计算幂运算的算法。计算复杂度 O(log n)基本思想是利用指数 n 的二进制展开形式&#xff0c;将 转化为多个 a 的幂的乘积&#xff0c;然后通过迭代快速计算。 快速幂的示例代码&…

鸿蒙开发系列教程(二十一)--轮播处理

轮播处理 Swiper本身是一个容器组件&#xff0c;当设置了多个子组件后&#xff0c;可以对这些子组件进行轮播显示 在自身尺寸属性未被设置时&#xff0c;会自动根据子组件的大小设置自身的尺寸 参数&#xff1a; 通过loop属性控制是否循环播放&#xff0c;该属性默认值为tr…