这实际上是一个看似“简单”的问题,但实际上是 Android 开发背景下的一个复杂问题。
活动是“进程入口点”,这意味着您看到的任何活动都可以充当“启动时应用程序的第一个入口点”。人们认为只有带有MAIN/LAUNCHER
intent filter的Activity才能在启动时启动,但这是错误的。
任何Activity 都可以充当“第一个 Activity”,因为 Android 可以使用当前活动的导航堆栈从任意点重新启动它。
无论如何,考虑到这一点,一个 Activity 可以显示一个View
,人们经常使用 Activity 来保存他们应用程序的每个屏幕(而不是将其用作入口点,并在其中交换视图控制器〜片段)。
因此,如果您有多个活动,那么您需要以这样一种方式在它们之间共享数据,您需要考虑到这两个活动都可以作为应用程序的第一个活动随时启动 。
为此,您需要做的不是“直接从另一个类设置文本视图的文本”,而是需要修改可观察的共享数据。
新发布的官方Android 架构组件提供了LiveData<T>
该类,该类有一个名为MutableLiveData<T>
.
要将数据从一个类更新到另一个 Activity,您必须做的是将全局数据公开为 LiveData
public class MyApplication extends Application {
private static MyApplication INSTANCE;
DataRepository dataRepository; // this is YOUR class
@Override
public void onCreate() {
super.onCreate();
INSTANCE = this;
dataRepository = new DataRepository();
}
public static MyApplication get() {
return INSTANCE;
}
}
DataRepository
应该公开 LiveData :
public class DataRepository {
private final MutableLiveData<MyData> data = new MutableLiveData<>();
public LiveData<MyData> getMyData() {
return data;
}
public void updateText(String text) {
MyData newData = data.getValue()
.toBuilder() // immutable new copy
.setText(text)
.build();
data.setValue(newData);
}
}
Activity 订阅此内容的地方:
public class MyActivity extends BaseActivity {
DataRepository dataRepository;
TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApplication app = (MyApplication)getApplicationContext();
dataRepository = app.getDataRepository();
setContentView(R.layout.main_activity);
textView = findViewById(R.id.textview);
dataRepository.getMyData().observe(this, new Observer() {
@Override
public void onChange(MyObject myObject) {
textView.setText(myObject.getText());
}
}
}
因此,要更新此文本,您需要获取DataRepository
该类并调用updateText
它:
DataRepository dataRepository = MyApplication.get().dataRepository();
dataRepository.updateText("my new text");
这将正确更新您的活动文本视图。
请注意,您还应该将数据持久化,onSaveInstanceState(Bundle
以免丢失(假设数据不是来自磁盘)。
为此,您需要执行以下操作:
public class BaseActivity extends AppCompatActivity {
DataRepository dataRepository;
private static boolean didRestoreGlobals = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
MyApplication app = (MyApplication)getApplicationContext();
dataRepository = app.getDataRepository();
super.onCreate(savedInstanceState);
if(!didRestoreGlobals) {
didRestoreGlobals = true;
if(savedInstanceState != null) {
dataRepository.restoreState(savedInstanceState.getBundle("dataRepository"));
}
}
}
@Override
protected void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putBundle("dataRepository", dataRepository.saveState());
}
}
然后相应地添加saveState/restoreState
方法DataRepository
。