Android 生命周期架构组件使用方法

yizhihongxing

Android 生命周期架构组件使用方法

Android 生命周期架构组件是为了帮助程序员更方便地管理应用的生命周期而设计的。在本文中,我们将详细讲解 Android 生命周期架构组件的使用方法。

组件介绍

Android 生命周期架构组件包括以下几个组件:

  • ViewModel:负责管理 UI 周期内需要保留的数据。
  • LiveData:用于展示数据变化,并帮助数据的观察者们自动更新数据。
  • LifecycleObserver:负责监听组件的生命周期,并进行相应的操作。

使用步骤

1. 导入组件

首先,需要在项目的 build.gradle 文件中,添加以下依赖:

dependencies {
    def lifecycle_version = "2.2.0"
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" //如果需要使用Java 8接口默认方法
}

2. 创建 ViewModel

创建 ViewModel 类,继承 ViewModel。在 ViewModel 类中,添加需要保留的数据和对应的 get/set 方法。例如:

public class MyViewModel extends ViewModel {
    private MutableLiveData<Integer> count = new MutableLiveData<>();

    public void setCount(int c) {
        count.setValue(c);
    }

    public LiveData<Integer> getCount() {
        return count;
    }
}

3. 观察 LiveData

在 Activity 或 Fragment 中,通过 ViewModelProviders 获取 ViewModel 实例,并观察 ViewModel 中的 LiveData。例如:

public class MainActivity extends AppCompatActivity {
    private TextView textView;
    private MyViewModel myViewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = findViewById(R.id.text_view);

        myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        myViewModel.getCount().observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                textView.setText("Count: " + integer);
            }
        });
    }

    public void increaseCount(View view) {
        myViewModel.setCount(myViewModel.getCount().getValue() + 1);
    }
}

在上面的代码中,TextView 的内容会自动随着 MyViewModel 的数据变化而更新。

4. 监听 Lifecycle

在需要监听生命周期的组件中,实现 LifecycleObserver 接口,并在对应的生命周期方法中进行相应的操作。例如:

public class MyLifecycleObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void connectListener() {
        // 连接监听器
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void disconnectListener() {
        // 断开监听器
    }
}

然后,在需要监听生命周期的组件中,创建 MyLifecycleObserver 实例,并添加到对应的 LifecycleOwner 上。例如:

public class MainActivity extends AppCompatActivity {
    private MyLifecycleObserver myLifecycleObserver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myLifecycleObserver = new MyLifecycleObserver();
        getLifecycle().addObserver(myLifecycleObserver);
    }
}

在上面的代码中,MyLifecycleObserver 的 connectListener 方法会在 Activity 启动时被调用,而 disconnectListener 方法会在 Activity 停止时被调用。

示例说明

下面我们来看两个根据业务需求而设计的不同使用示例:

示例一

你需要记录用户阅读文章的时间,并在应用退出时保存,下次进入时恢复。这里的时间数据需要在整个应用生命周期中保留,既不应随着 Activity 的销毁而消失,也不应该持久化到本地存储。

实现方法如下:

  1. 使用 ViewModel 将时间数据保留。ViewModel 需要继承自 AndroidX 的 ViewModel 类,并将时间数据包裹在 LiveData 中:
public class ReadingTimeViewModel extends ViewModel {
    private MutableLiveData<Long> readingTime = new MutableLiveData<>();

    public void setReadingTime(long time) {
        readingTime.setValue(time);
    }

    public LiveData<Long> getReadingTime() {
        return readingTime;
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        Log.d(TAG, "onCleared: ");
    }
}
  1. 在 Activity 中使用 ViewModelProviders 获取 ViewModel 的实例,并观察 ViewModel 中的数据。需要注意的是,在 ViewModelProviders.of 方法中传入的对象应该指定为应用的整个生命周期:
public class MainActivity extends AppCompatActivity {
    private ReadingTimeViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewModel = ViewModelProviders.of(getApplication()).get(ReadingTimeViewModel.class);
        viewModel.getReadingTime().observe(this, time -> Log.d(TAG, "onChanged: time = " + time));
    }

    @Override
    protected void onDestroy() {
        viewModel.setReadingTime(System.currentTimeMillis());
        super.onDestroy();
    }
}
  1. 在 Application 类中实现 LifecycleCallbacks 接口,并在对应的生命周期方法中添加对 ViewModeles 的存储和清除逻辑:
public class MyApp extends Application implements LifecycleObserver {
    private static final String SHARED_PREF_NAME = "ReadingTimePref";
    private static final String KEY_READING_TIME = "readingTime";
    private ReadingTimeViewModel viewModel;
    private SharedPreferences sharedPreferences;

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
        sharedPreferences = getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
        viewModel = ViewModelProviders.of(this).get(ReadingTimeViewModel.class);
        viewModel.setReadingTime(sharedPreferences.getLong(KEY_READING_TIME, 0));
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void saveReadingTime() {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putLong(KEY_READING_TIME, viewModel.getReadingTime().getValue());
        editor.apply();
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void clearViewModel() {
        viewModel.setReadingTime(0);
    }
}

在上面的示例中,我们通过使用 ViewModel 和 LifecycleCallbacks 完成了将应用在内存中保持时间数据,不保存到本地存储,同时还实现了在应用退出时保存用户阅读时间,下次应用启动时自动恢复的功能。

示例二

你需要展示一个列表,列表的数据存在本地存储中,并需要在 Activity 被关闭时进行保存。当用户在列表中点击一个 item 时,需要带着 item 的 id 跳转到一个新的 Activity,在新的 Activity 中显示 item 的详细信息。在新的 Activity 中,用户可以修改 item 的信息,当用户保存修改并返回时,应该更新列表中对应 item 的信息,并持久化到本地存储中。

实现方法如下:

  1. 在 ViewModel 中添加一个 LiveData,用于保存 item 的列表数据:
public class ItemViewModel extends ViewModel {
    private MutableLiveData<List<Item>> items;

    public LiveData<List<Item>> getItems() {
        if (items == null) {
            items = new MutableLiveData<>();
            loadItems();
        }
        return items;
    }

    private void loadItems() {
        // 从本地存储中读取数据并解析为 List<Item>,然后通过 postValue 发送数据
    }

    public void saveItems(List<Item> items) {
        // 保存数据到本地存储
    }
}
  1. 在 Activity 中,使用 ViewModelProviders 获取 ViewModel 实例,并观察该实例中 items 数据的变化。同时,在 Activity 的 onDestroy 或 onSaveInstanceState 中保存 items 数据到本地存储中:
public class ListActivity extends AppCompatActivity {
    private ItemViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);

        viewModel = ViewModelProviders.of(this).get(ItemViewModel.class);
        viewModel.getItems().observe(this, items -> {
            // 更新列表
        });
    }

    @Override
    protected void onDestroy() {
        List<Item> items = // 获取列表的数据
        viewModel.saveItems(items);
        super.onDestroy();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        List<Item> items = // 获取列表的数据
        viewModel.saveItems(items);
        super.onSaveInstanceState(outState);
    }
}
  1. 在点击 item 后的 Activity 中,使用 Intent 传递 item 的 id,并在 Activity 的 onCreate 中根据该 id 加载 item 的数据,并显示在 UI 上。在用户修改并保存 item 数据后,返回到列表页面:
public class DetailActivity extends AppCompatActivity {
    private ItemViewModel viewModel;
    private Item item;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);

        viewModel = ViewModelProviders.of(this).get(ItemViewModel.class);

        int itemId = // 从 Intent 中获取 item 的 id
        item = // 根据 id 加载 item 的数据
        // 在 UI 上显示 item 的信息

        Button saveButton = findViewById(R.id.save_button);
        saveButton.setOnClickListener(view -> {
            // 将 UI 上的数据更新到 item 中
            item.setName("new name");
            item.setDescription("new description");
            item.setCreatedAt(System.currentTimeMillis());

            viewModel.getItems().getValue().set(getIndex(item), item);
            viewModel.saveItems(viewModel.getItems().getValue());

            finish();
        });
    }

    private int getIndex(Item item) {
        // 根据 item 在列表中查找其对应的 index
    }
}

在上面的示例中,我们通过使用 ViewModel 和 LiveData 完成了在列表页面和详情页面之间传递数据,并且在详情页面中更新数据,并返回到列表页面时自动刷新并持久化数据。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android 生命周期架构组件使用方法 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • ninja编译过程分析

    ninja编译过程分析 在软件项目开发过程中,编译是不可避免的环节。编译器在将源代码转化为目标代码时,需要经过一系列的过程。其中,包括代码预处理、编译、汇编和链接。这些过程被称为编译过程。在大型软件项目中,编译时间常常非常长。为了缩短编译时间,需要使用高效的编译工具。 ninja就是一种高效的编译工具。在这篇文章中,我们将对ninja编译过程进行分析。 ni…

    其他 2023年3月28日
    00
  • react自动化构建路由的实现

    React自动化构建路由的实现攻略 React是一个流行的JavaScript库,用于构建用户界面。在React应用中,路由是一个重要的概念,用于管理不同页面之间的导航和状态。本攻略将详细介绍如何使用React自动化构建路由。 步骤1:安装所需的依赖 首先,我们需要安装React Router库,它是React应用中最常用的路由库。可以使用以下命令来安装Re…

    other 2023年7月28日
    00
  • windows10系统电脑中如何听收音机

    当然,我很乐意为您提供关于“windows10系统电脑中如何听收音机”的完整攻略。以下是详细的步骤说明: 步骤说明 1.先,您需要购买一个音机硬件设备,并将其连接到您的Windows 10系统电上。收音机硬件设备通会附带一个USB接口或频接口,您可以将其插入到电脑的相应接口上。 接下来,您需要开Windows 10系统电脑,并进“控制面板”。您可以通过在Wi…

    other 2023年5月9日
    00
  • vue draggable组件实现拖拽及点击无效问题的解决

    Vue Draggable 组件实现拖拽及点击无效问题的解决攻略 标题 在这个攻略中,我们将详细讲解如何使用 Vue Draggable 组件实现拖拽功能,并解决由此引发的点击无效问题。 示例说明1: 基本拖拽功能 首先,我们需要安装 Vue Draggable 组件。可以通过以下命令在项目中进行安装: npm install vuedraggable 安装…

    other 2023年6月28日
    00
  • 常见的10种图片格式(文件后缀)和使用场景(方便选择不同的后缀)

    常见的10种图片格式及使用场景攻略 在选择图片格式时,了解不同格式的特点和适用场景非常重要。下面是常见的10种图片格式及其使用场景的详细攻略: 1. JPEG (.jpg/.jpeg) 特点: JPEG 是一种有损压缩格式,可以在保持较高质量的同时减小文件大小。 使用场景: JPEG 格式适用于存储照片、图像和复杂的图形,如数字摄影、网页图像和社交媒体分享。…

    other 2023年8月5日
    00
  • 详解java封装返回结果与RestControllerAdvice注解

    下面是详解java封装返回结果与RestControllerAdvice注解的完整攻略: 1. 什么是封装返回结果? 在Web开发中,我们经常需要向用户返回数据,例如:查询结果、错误信息、操作成功等等。但是,直接返回结果有时候不太灵活,可能会导致一些问题,例如:字段暴露、无法扩展、难以维护等等。为了解决这些问题,我们可以使用封装返回结果的方式来实现。即:在返…

    other 2023年6月25日
    00
  • APNS推送服务证书制作 图文详解教程(新)

    APNS推送服务证书制作 图文详解教程(新) 什么是APNS APNS,全称为Apple Push Notification Service,是由苹果公司提供的一项推送服务,通过该服务开发者可以将消息、通知等实时推送到用户的iOS设备上,从而帮助用户获取最新的消息和提醒,提高用户体验。 为什么需要APNS证书 在使用APNS服务之前,我们需要事先在苹果开发者…

    其他 2023年3月28日
    00
  • Android Studio多渠道打包套路

    Android Studio多渠道打包套路 在Android开发中,多渠道打包是常见的需求,它允许我们根据不同的渠道需求生成不同的APK文件。下面是使用Android Studio进行多渠道打包的一般套路: 配置渠道信息 在项目的build.gradle文件中,我们可以使用productFlavors来配置不同的渠道信息。例如: groovy android…

    other 2023年10月13日
    00
合作推广
合作推广
分享本页
返回顶部