我一直在寻找一种解决方案,让我的应用程序在电话方向改变时不会丢失数据。我找到了一个,它正在添加这行代码
android:configChanges="orientation|keyboardHidden">
到android清单。所以我做到了:
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
当方向发生变化时,我的数据仍会丢失,有人可以帮助我吗?非常感谢你。
我的java代码:
public class MainActivity extends AppCompatActivity {
int scoreofShooter1 = 0;
int scoreofShooter2 = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void addOneForShooter1(View view) {
scoreofShooter1 = scoreofShooter1 + 1;
displayForShooter1(scoreofShooter1);
}
public void addTwoForShooter1(View view) {
scoreofShooter1 = scoreofShooter1 + 2;
displayForShooter1(scoreofShooter1);
}
public void addThreeForShooter1(View view) {
scoreofShooter1 = scoreofShooter1 + 3;
displayForShooter1(scoreofShooter1);
}
public void addFourForShooter1(View view) {
scoreofShooter1 = scoreofShooter1 + 4;
displayForShooter1(scoreofShooter1);
}
public void addOneForShooter2(View view) {
scoreofShooter2 = scoreofShooter2 + 1;
displayForShooter2(scoreofShooter2);
}
public void addTwoForShooter2(View view) {
scoreofShooter2 = scoreofShooter2 + 2;
displayForShooter2(scoreofShooter2);
}
public void addThreeForShooter2(View view) {
scoreofShooter2 = scoreofShooter2 + 3;
displayForShooter2(scoreofShooter2);
}
public void addFourForShooter2(View view) {
scoreofShooter2 = scoreofShooter2 + 4;
displayForShooter2(scoreofShooter2);
}
public void resetScoreOfShooter1(View view) {
scoreofShooter1 = 0;
displayForShooter1(scoreofShooter1);
}
public void resetScoreOfShooter2(View view) {
scoreofShooter2 = 0;
displayForShooter2(scoreofShooter2);
}
public void displayForShooter1(int score) {
TextView scoreView = (TextView) findViewById(R.id.shooter_1_score);
scoreView.setText(String.valueOf(score));
}
public void displayForShooter2(int score) {
TextView scoreView = (TextView) findViewById(R.id.shooter_2_score);
scoreView.setText(String.valueOf(score));
}
}
答案 0 :(得分:1)
改变这个:
android:configChanges="orientation|keyboardHidden">
为:
android:configChanges="orientation|keyboardHidden|screenSize">
“取向”: 屏幕方向已更改 - 用户已旋转 设备。
注意:如果您的应用程序的目标是API级别13或更高级别(如声明的那样) 通过minSdkVersion和targetSdkVersionattributes),那么你应该 还声明了“screenSize”配置,因为它也会发生变化 当设备在纵向和横向之间切换时。
答案 1 :(得分:0)
您的解决方案是不正确的做法,如great article
所述也许最讨厌和最广泛滥用的解决方法是通过在Android清单中设置android:configChanges属性来禁用默认的销毁和重新创建行为。这种方法显而易见的简单性使其对开发人员极具吸引力;但是,Google工程师不鼓励使用它。主要问题是它需要您在代码中手动处理设备配置更改。处理配置更改需要您采取许多额外步骤,以确保每个字符串,布局,可绘制,尺寸等与设备的当前配置保持同步,如果您不小心,您的应用程序可以轻松拥有一个整体一系列特定于资源的错误。
Google不鼓励使用它的另一个原因是因为很多 开发人员错误地认为设置 android:configChanges =“orientation”(例如)会神奇地 保护他们的应用程序免受不可预测的情况的影响 底层Activity将被销毁并重新创建。这不是 案件。配置更改可能由于多种原因而发生 - 不仅仅是 屏幕方向改变。将设备插入显示器底座, 更改默认语言,并修改设备的默认字体 缩放因子只是可以触发a的事件的三个例子 设备配置更改,所有这些都表示系统要销毁 并在下次重新创建所有当前正在运行的活动 恢复。因此,设置android:configChanges属性是 通常不是很好的做法。
有两种情况:
1-如果您只需要保存一些属性,只需使用onSavedInstanceState
和onRestoreInstanceState
2-如果你有一个更复杂的场景,你运行了Threads,AsyncTasks,Sockets。 你可以:
1-按照here
所述管理保留片段内的对象2-更好的解决方案是使用创建的loaders来解决这个问题。
来自android docs:
如果您直接在活动或片段中获取数据,则由于从UI线程执行可能较慢的查询,您的用户将因缺乏响应而受到影响。
如果您从另一个线程获取数据,可能使用AsyncTask,那么您负责管理线程和UI线程 通过各种活动或片段生命周期事件,例如 onDestroy()和配置更改。
装载机解决了这些问题并包含其他好处。例如:
加载程序在不同的线程上运行,以防止janky或无响应的UI。 加载程序通过在何时提供回调方法来简化线程管理 事件发生。加载程序持久存储并在配置中缓存结果 更改以防止重复查询。装载机可以实现 观察者监视底层数据源的变化。对于 例如,CursorLoader自动注册ContentObserver 数据更改时触发重新加载。
针对您的具体情况
使用以下代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
scoreofShooter1 = savedInstanceState.getInt("scoreofShooter1");
scoreofShooter2 = savedInstanceState.getInt("scoreofShooter2");
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("scoreofShooter1", scoreofShooter1);
outState.putInt("scoreofShooter2", scoreofShooter2);
}