Android方向改变丢失数据解决方案不起作用

时间:2017-03-31 21:06:44

标签: android android-studio android-manifest android-orientation

我一直在寻找一种解决方案,让我的应用程序在电话方向改变时不会丢失数据。我找到了一个,它正在添加这行代码

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));
}

}

2 个答案:

答案 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-如果您只需要保存一些属性,只需使用onSavedInstanceStateonRestoreInstanceState

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);
}