如何在启动另一个时保存变量值 activity
How to save a variable value when starting another activity
我在应用程序中进行的一项活动 (Activity A) 会显示视频列表,如您在图片中所见:
视频存储在名为 videosList 的 ArrayList 中,当用户 select 播放视频时,视频将使用另一个 activity 中的嵌入式 YouTube 播放器播放 B.
问题是当用户从 activity B(带有视频播放器的 activity)返回到 activity A(带有视频列表的 activity)变量 videosList为空,因此应用程序停止 运行 错误。
我尝试实施
protected void onSaveInstanceState(Bundle savedInstanceState)
和
protected void onRestoreInstanceState(Bundle savedInstanceState)
方法保存 activity 状态和一些变量,因此当用户返回 Activity A 时,应用程序可以显示列表再次播放视频,但是当我尝试在 public void onCreate(Bundle savedInstanceState)
中获取之前保存在 onSaveInstanceState(Bundle savedInstanceState)
中的值时,savedInstanceState
始终为 NULL。
这是我的代码:
public class VideosCatalogActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private Toolbar toolbar;
private GridView videosGrid;
private ArrayList<VideoEntity> videosList;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseDatabase database;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, " onCreate(Bundle) - Ini ");
super.onCreate(savedInstanceState);
// onSaveInstanceState();
setContentView(R.layout.videos_catalog_layout);
toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
toolbar.setTitle(R.string.app_name);
toolbar.setTitleTextColor(getResources().getColor(R.color.com_facebook_button_background_color_focused));
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = mAuth.getCurrentUser();
}
};
database = FirebaseDatabase.getInstance();
Bundle bundle = getIntent().getExtras();
String actividad = bundle.getString("Activity");
if (actividad.equals("DocumentariesCategoriesActivity")) {
videosList = bundle.getParcelableArrayList("com.app.example.VideoEntity");
updateCatalog();
/*
String videoId = "";
if (!videosList.isEmpty() && !videosList.equals(null)) {
for (VideoEntity video : videosList) {
DatabaseReference mRef = database.getReference().child("Videos").child(video.getId());
mRef.setValue(video);
}
videosGrid = (GridView) findViewById(R.id.videosGrid);
MyGridViewAdapter adapter = new MyGridViewAdapter(this);
adapter.setVideosList(videosList);
videosGrid.setAdapter(adapter);
videosGrid.setOnItemClickListener(this);
} */
}
Log.d(TAG, " onCreate(Bundle) - Fi ");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d(TAG, "onCreateOptionsMenu(Menu) - Ini");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
Log.d(TAG, "onCreateOptionsMenu(Menu) - Fi");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
Log.d(TAG, "onOptionItemSelected(MenuItem) - Ini");
switch (menuItem.getItemId()) {
case R.id.action_logout:
updateActivity(mAuth.getCurrentUser());
}
Log.d(TAG, "onOptionItemSelected(MenuItem) - Fi");
return true;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, " onItemClick(AdapterView<?>, View, int, long) - Ini ");
Intent intent = new Intent(getApplicationContext(), YoutubePlayerActivity.class);
intent.putExtra("VIDEO_ID", videosList.get(position).getId());
startActivity(intent);
Log.d(TAG, " onItemClick(AdapterView<?>, View, int, long) - Fi ");
}
protected void updateActivity(FirebaseUser user) {
Log.d(TAG, "updateActivity(FirebaseUser) - Ini");
mAuth.signOut();
Intent i = new Intent(VideosCatalogActivity.this, LoginActivity.class);
startActivity(i);
Log.d(TAG, "updateActivity(FirebaseUser) - Fi");
}
@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "onSaveInstanceState(Bundle) - Ini");
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putParcelableArrayList("VIDEOS_LIST", videosList);
savedInstanceState.putAll(savedInstanceState);
Log.d(TAG, "onSaveInstanceState(Bundle) - Fi");
Log.i("","onSaveInstance is executed");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "onRestoreInstanceState(Bundle) - Ini");
super.onRestoreInstanceState(savedInstanceState);
videosList = savedInstanceState.getParcelableArrayList("VIDEOS_LIST");
updateCatalog();
Log.i("","onRestoreInstance is executed");
Log.d(TAG, "onRestoreInstanceState(Bundle) - Fi");
}
protected void updateCatalog() {
Log.d(TAG, "updateCatalog() - Ini");
String videoId = "";
for (VideoEntity video : videosList) {
DatabaseReference mRef = database.getReference().child("Videos").child(video.getId());
mRef.setValue(video);
}
videosGrid = (GridView) findViewById(R.id.videosGrid);
MyGridViewAdapter adapter = new MyGridViewAdapter(this);
adapter.setVideosList(videosList);
videosGrid.setAdapter(adapter);
videosGrid.setOnItemClickListener(this);
Log.d(TAG, "updateCatalog() - Fi");
}
}
请问我该如何解决这个问题?
为什么不使用 SingletonDataclass?存储 ArrayList,当您需要重新加载 ArrayList 时,您可以从 Singleton 加载它。
public class DataSingleton {
private static DataSingleton instance = new DataSingleton();
private DataSingleton(){ }
public static DataSingleton getInstance(){ return instance; }
public static void setIntances(DataSingleton instance){DataSingleton.instance = instance;}
private ArrayList<Videos> videosList;
public void setArrayVideos(ArrayList<Videos> videos){
videosList=videos;
}
public ArrayList<Videos> getArrayVideos(){
return videosList;
}
}
然后在 activity A 中调用 class 并在任意位置设置 ArrayList。
DataSingleton.getInstance().setArrayVideos(videosList);
videosList= DataSingleton.getInstance().getArrayVideos();
您的 onSaveInstanceState 实现必须像这样
@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "onSaveInstanceState(Bundle) - Ini");
if(savedInstanceState == null)
{
savedInstanceState = new Bundle();
}
savedInstanceState.putParcelableArrayList("VIDEOS_LIST", videosList);
Log.d(TAG, "onSaveInstanceState(Bundle) - Fi");
Log.i("","onSaveInstance is executed");
super.onSaveInstanceState(savedInstanceState);
}
我在应用程序中进行的一项活动 (Activity A) 会显示视频列表,如您在图片中所见:
我尝试实施
protected void onSaveInstanceState(Bundle savedInstanceState)
和
protected void onRestoreInstanceState(Bundle savedInstanceState)
方法保存 activity 状态和一些变量,因此当用户返回 Activity A 时,应用程序可以显示列表再次播放视频,但是当我尝试在 public void onCreate(Bundle savedInstanceState)
中获取之前保存在 onSaveInstanceState(Bundle savedInstanceState)
中的值时,savedInstanceState
始终为 NULL。
这是我的代码:
public class VideosCatalogActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private Toolbar toolbar;
private GridView videosGrid;
private ArrayList<VideoEntity> videosList;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseDatabase database;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, " onCreate(Bundle) - Ini ");
super.onCreate(savedInstanceState);
// onSaveInstanceState();
setContentView(R.layout.videos_catalog_layout);
toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
toolbar.setTitle(R.string.app_name);
toolbar.setTitleTextColor(getResources().getColor(R.color.com_facebook_button_background_color_focused));
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = mAuth.getCurrentUser();
}
};
database = FirebaseDatabase.getInstance();
Bundle bundle = getIntent().getExtras();
String actividad = bundle.getString("Activity");
if (actividad.equals("DocumentariesCategoriesActivity")) {
videosList = bundle.getParcelableArrayList("com.app.example.VideoEntity");
updateCatalog();
/*
String videoId = "";
if (!videosList.isEmpty() && !videosList.equals(null)) {
for (VideoEntity video : videosList) {
DatabaseReference mRef = database.getReference().child("Videos").child(video.getId());
mRef.setValue(video);
}
videosGrid = (GridView) findViewById(R.id.videosGrid);
MyGridViewAdapter adapter = new MyGridViewAdapter(this);
adapter.setVideosList(videosList);
videosGrid.setAdapter(adapter);
videosGrid.setOnItemClickListener(this);
} */
}
Log.d(TAG, " onCreate(Bundle) - Fi ");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d(TAG, "onCreateOptionsMenu(Menu) - Ini");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
Log.d(TAG, "onCreateOptionsMenu(Menu) - Fi");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
Log.d(TAG, "onOptionItemSelected(MenuItem) - Ini");
switch (menuItem.getItemId()) {
case R.id.action_logout:
updateActivity(mAuth.getCurrentUser());
}
Log.d(TAG, "onOptionItemSelected(MenuItem) - Fi");
return true;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, " onItemClick(AdapterView<?>, View, int, long) - Ini ");
Intent intent = new Intent(getApplicationContext(), YoutubePlayerActivity.class);
intent.putExtra("VIDEO_ID", videosList.get(position).getId());
startActivity(intent);
Log.d(TAG, " onItemClick(AdapterView<?>, View, int, long) - Fi ");
}
protected void updateActivity(FirebaseUser user) {
Log.d(TAG, "updateActivity(FirebaseUser) - Ini");
mAuth.signOut();
Intent i = new Intent(VideosCatalogActivity.this, LoginActivity.class);
startActivity(i);
Log.d(TAG, "updateActivity(FirebaseUser) - Fi");
}
@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "onSaveInstanceState(Bundle) - Ini");
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putParcelableArrayList("VIDEOS_LIST", videosList);
savedInstanceState.putAll(savedInstanceState);
Log.d(TAG, "onSaveInstanceState(Bundle) - Fi");
Log.i("","onSaveInstance is executed");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "onRestoreInstanceState(Bundle) - Ini");
super.onRestoreInstanceState(savedInstanceState);
videosList = savedInstanceState.getParcelableArrayList("VIDEOS_LIST");
updateCatalog();
Log.i("","onRestoreInstance is executed");
Log.d(TAG, "onRestoreInstanceState(Bundle) - Fi");
}
protected void updateCatalog() {
Log.d(TAG, "updateCatalog() - Ini");
String videoId = "";
for (VideoEntity video : videosList) {
DatabaseReference mRef = database.getReference().child("Videos").child(video.getId());
mRef.setValue(video);
}
videosGrid = (GridView) findViewById(R.id.videosGrid);
MyGridViewAdapter adapter = new MyGridViewAdapter(this);
adapter.setVideosList(videosList);
videosGrid.setAdapter(adapter);
videosGrid.setOnItemClickListener(this);
Log.d(TAG, "updateCatalog() - Fi");
}
}
请问我该如何解决这个问题?
为什么不使用 SingletonDataclass?存储 ArrayList,当您需要重新加载 ArrayList 时,您可以从 Singleton 加载它。
public class DataSingleton {
private static DataSingleton instance = new DataSingleton();
private DataSingleton(){ }
public static DataSingleton getInstance(){ return instance; }
public static void setIntances(DataSingleton instance){DataSingleton.instance = instance;}
private ArrayList<Videos> videosList;
public void setArrayVideos(ArrayList<Videos> videos){
videosList=videos;
}
public ArrayList<Videos> getArrayVideos(){
return videosList;
}
}
然后在 activity A 中调用 class 并在任意位置设置 ArrayList。
DataSingleton.getInstance().setArrayVideos(videosList);
videosList= DataSingleton.getInstance().getArrayVideos();
您的 onSaveInstanceState 实现必须像这样
@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "onSaveInstanceState(Bundle) - Ini");
if(savedInstanceState == null)
{
savedInstanceState = new Bundle();
}
savedInstanceState.putParcelableArrayList("VIDEOS_LIST", videosList);
Log.d(TAG, "onSaveInstanceState(Bundle) - Fi");
Log.i("","onSaveInstance is executed");
super.onSaveInstanceState(savedInstanceState);
}