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

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日

相关文章

  • openstack中的rpc远程调用的方法

    OpenStack中RPC远程调用的方法 RPC(Remote Procedure Call)是一种进程间通信机制,允许在不同的计算机上的进程之间进行调用。在OpenStack中,RPC用于在不同节点间的服务进程通讯,充当了OpenStack分发服务的核心。下面是RPC远程调用的方法。 1. RPC远程调用简介 RPC远程调用是通过消息传输的方式进行数据的交…

    other 2023年6月27日
    00
  • 如何使用xwpf在worddoc中以相同格式保存富文本区域内容

    如何使用xwpf在Word文档中以相同格式保存富文本区域内容 在Java中,我们可以使用Apache POI库中的xwpf模块来操作文档。本文将介绍如何使用xwpf在Word文档以相同格式保存富文本区域内容。 1. 导入依赖 首先,我们需要在项目中导入Apache POI库的依赖。在Maven项目中,我们可以在pom.xml文件中添加以下依赖: <de…

    other 2023年5月8日
    00
  • sed使用删除匹配行

    以下是详细讲解“sed使用删除匹配行的完整攻略,过程中至少包含两条示例说明”的标准Markdown格式文本: sed使用删除匹配行 sed是一种流编辑器,可以用于对文本进行编辑和转换。其中,删除匹配行是sed的一种常见用法。本攻略将介绍如何使用sed删除匹配行,包括基本语法和常用选项。同时,本攻略还提供了两个示例说明,帮助您更好地理解和应用这些技术。 基本语…

    other 2023年5月10日
    00
  • 使用python网络抓取google新闻

    使用Python网络抓取Google新闻是一项非常有用的技能,可以帮助您获取最新的新闻和信息。本文将提供一个完整的攻略,包括Python进行网络抓取的基本知识和两个示例说明。 基本知识 在使用Python进行网络抓取之前,您需要了解基本知识: 网络请求:使用Python发送HTTP请求来获取网页内容。 解析HTML:使用Python解析HTML文档,以便从中…

    other 2023年5月7日
    00
  • json数据进行sql查询

    json数据进行SQL查询 在现代的应用程序中,JSON(JavaScript Object Notation)已经成为最常用的数据交换格式之一。随着日益增长的JSON数据存储,在许多情况下,我们需要使用SQL查询来检索JSON对象中特定属性的值。在本文中,我们将提供一些关于如何在SQL中使用JSON数据的指导。 使用JSON函数 SQL 2016 引入了几…

    其他 2023年3月28日
    00
  • Android实战–电话拨号器

    Android实战–电话拨号器的完整攻略 在Android应用程序中,我们可以使用电话拨号器来拨打电话。本文将介绍如何在Android应用程序中实现电话拨号器,包括权限申请、UI设计、拨号功能实现等。 1. 权限申请 在Android应用程序中,我们需要申请CALL_PHONE权限才能拨打电话。在AndroidManifest.xml文件中添加以下代码: …

    other 2023年5月5日
    00
  • div的显示隐藏方法汇总

    当然,我很乐意为您提供有关“div的显示隐藏方法汇总”的完整攻略。以下是详细的步骤和两个示例: 1. div是什么? div是HTML中的一个标签,用于定义文档中的一个区域。div标签可以用于布局和样式控制,可以包含其他HTML元素。 以下是div标签的基本语法: <div>content</div> 在这个示例中,我们使用div标签…

    other 2023年5月6日
    00
  • 文件夹右键属性与双击打开的属性不一样怎么办?

    文档或文件夹属性指的是文件管理器中显示的有关文件或文件夹的信息,并提供了对其进行更改的选项。一些用户可能会发现,在单击文件夹右键并选择“属性”后,打开窗口中的某些属性与双击打开文件夹时看到的实际属性不一致,这可能会导致混淆和错误。下面是解决此问题的完整攻略: 1. 清空Windows资源管理器缓存 首先,尝试清空Windows资源管理器缓存可能会解决文件夹属…

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