【问题标题】:How do I save variable values across Activities in Android Studio如何在 Android Studio 中跨活动保存变量值
【发布时间】:2020-07-15 11:42:11
【问题描述】:

我是新来的,也是编程新手。我目前正在做一个项目,现在我已经被困了一周。我唯一想做的就是保存两个变量,以便在应用程序关闭并重新打开后仍然可以看到它。同样由于某种原因,当我打开设置活动时,我的变量值被设置回零。

我知道其他人已经发布了类似的问题,但我无法将其应用于我的工作。我不明白我读到的很多东西,比如 SharedPreferences、onPause() 和 GAME_STATE_KEY。任何人都可以在不链接 Android 文档文章的情况下解释如何做这样的事情吗?我什至不明白文档说什么,复制/粘贴代码似乎不起作用。

这是我的 MainActivity

package com.example.courtcounter;

import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity<format> extends AppCompatActivity {


    TextView textView;

     int scoreTeamA = 0;
     int scoreTeamB = 0;


    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy\n hh:mm aa");
    String format = simpleDateFormat.format(new Date());


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.team_a_score);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                String shareMessage = createMessage(format, scoreTeamA, scoreTeamB);

                Intent intent = new Intent(Intent.ACTION_SEND);
                intent.putExtra(Intent.EXTRA_SUBJECT, "Match Score");
                intent.setType("text/*");
                intent.putExtra(Intent.EXTRA_TEXT, shareMessage);
                if (intent.resolveActivity(getPackageManager()) != null) {
                    startActivity(intent);
                }
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        if (id == R.id.action_settings){

            Intent intent = new Intent(this, SettingsActivity.class);
            startActivity(intent);

            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private String createMessage(String date, int TeamA, int TeamB){

        EditText editTeamA = findViewById(R.id.team_a_name);
        String teamAName =editTeamA.getText().toString();

        EditText editTeamB = findViewById(R.id.team_b_name);
        String teamBName = editTeamB.getText().toString();


        String shareMessage =format +"\n"+ teamAName+ " : "+ TeamA + "\n" + teamBName + " : "+ TeamB;
        return shareMessage;
    }


    /** Resets score of boths teams to 0
     */
    public void resetScore(View v){
        scoreTeamA = 0;
        scoreTeamB = 0;
        displayForTeamA(scoreTeamA);
        displayForTeamB(scoreTeamB);
    }

    /**
     * Displays the given score for Team A.
     */
    public void displayForTeamA(int scoreTeamA){
        TextView scoreViewA = (TextView)findViewById(R.id.team_a_score);
        String teamA = scoreViewA.getText().toString();
        scoreViewA.setText(String.valueOf(scoreTeamA));

    }

    /**
     * Displays the given score for Team B.
     */
    public void displayForTeamB(int score) {
        TextView scoreViewB = (TextView) findViewById(R.id.team_b_score);
        String teamB = scoreViewB.getText().toString();
        scoreViewB.setText(String.valueOf(score));
    }

    /**
     * This method is called when the +3 points button is clicked.
     */
    public void ThreeA(View view){
        scoreTeamA = scoreTeamA +3;
        displayForTeamA(scoreTeamA);
    }

    /**
     * This method is called when the +2 points button is clicked.
     */
    public void TwoA(View view){
        scoreTeamA = scoreTeamA +2;
        displayForTeamA(scoreTeamA);
    }

    /**
     * This method is called when the FREE THROW button is clicked.
     */
    public void OneA(View view){
        scoreTeamA = scoreTeamA + 1;
        displayForTeamA(scoreTeamA);
    }

    /**
     * This method is called when the +3 points button is clicked.
     */
    public void ThreeB(View view){
        scoreTeamB = scoreTeamB +3;
        displayForTeamB(scoreTeamB);
    }

    /**
     * This method is called when the +2 points button is clicked.
     */
    public void TwoB(View view){
        scoreTeamB = scoreTeamB +2;
        displayForTeamB(scoreTeamB);
    }

    /**
     * This method is called when the FREE THROW button is clicked.
     */
    public void OneB(View view){
        scoreTeamB = scoreTeamB + 1;
        displayForTeamB(scoreTeamB);
    }


}

我是否必须更改我的 SettingActivity 和 SettingsFragment 来帮助解决这个问题,还是不需要?

谢谢。

【问题讨论】:

    标签: java android


    【解决方案1】:

    如果您希望它们在应用程序完全关闭时仍然存在,SharedPreferences 就是您要寻找的那个。这是一个key/value 存储,它允许您存储即使在活动被销毁后仍然存在的数据。基本上,它们有两个部分:

    1. 密钥是用于访问数据的唯一标识符
    2. 该值是您尝试保存的实际数据

    因此,首先您可以使用

    获得对您共享偏好的参考
    SharedPreferences.Editor editor = getSharedPreferences(
      MY_PREFS_NAME, MODE_PRIVATE).edit();
    

    这个MY_PREFS_NAME 可以是你喜欢的任何字符串。它允许您访问共享首选项的“切片”。获得此参考资料后,您就可以开始阅读和写信给他们了。

    写作:

    editor.putInt("scoreViewA", 5);
    editor.putInt("scoreViewB", 12);
    editor.apply();
    

    稍后阅读:

    SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
    int scoreViewA = prefs.getInt("scoreViewA", 0);
    int scoreViewB = prefs.getInt("scoreViewB", 0);
    

    getInt 中的第二个参数是默认值,如果没有找到给定的键,将使用该参数。请注意,在检索对共享首选项的引用时,您必须再次使用相同的 MY_PREFS_NAME

    最后,请注意,在写入共享首选项时,我们在写入任何更改之前调用edit(),然后调用apply()

    您需要将您的代码写入您的onPause 方法中的共享首选项。只要活动不再在前台,就会触发。然后在onResume 方法中阅读。当应用在前台重新获得焦点时会触发此方法。

    @Override
    public void onPause() {
      super.onPause();
      // write to shared preferences
    }
    
    @Override
    public void onResume() {
      super.onResume();
      // read from shared preferences
    }
    

    如果您只是想将一个变量从一个活动共享到一个新活动,您可以使用捆绑包。看看this answer 就是一个很好的例子。

    希望对您有所帮助,欢迎使用 Stackoverflow!

    【讨论】:

    • 谢谢,虽然我还是有问题。该应用程序现在不断崩溃,在 logcat 中我看到“Caused by: java.lang.NullPointerException:Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a空对象引用”在SharedPreferences.Editor editor = getSharedPreferences("MY_PREFS_NAME", MODE_PRIVATE).edit();如何解决它,我尝试在 onCreate 类中声明 SharedPreferences.Editor 但它不起作用。 onPause() 和 onResume() 在 MainActivity 我还在尝试但 idk
    【解决方案2】:

    我终于想通了,这很宣泄。我的主要问题是弄清楚将方法放在哪里,看起来我不需要 onPause()onResume() 方法。

    首先在我添加的 AndroidManifest.xml 文件中 android:launchMode="singleTop" 但由于我设法保存了首选项,因此最终不需要它。

    在我的显示方法中我添加了 SharedPreferences myScoreB = getSharedPreferences("teamBScore", Context.MODE_PRIVATE); SharedPreferences.Editor editor = myScoreB.edit();editor.putInt("scoreB", scoreTeamB);editor.commit();

    读取数据部分令人困惑,但最后我设法在 oncreate 方法 SharedPreferences myScoreB = this.getSharedPreferences("teamBScore", Context.MODE_PRIVATE);scoreTeamB = myScoreB.getInt("scoreB", 0);scoreViewB.setText(String.valueOf(scoreTeamB)); 中做到了这一点

    它现在可以在不重新创建整个布局以及重新启动的情况下处理屏幕旋转。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 2018-01-13
      • 2020-04-26
      相关资源
      最近更新 更多