Android: 如何实现两个活动之间的值传递和更新?

5

我正在为一项活动制作定制的倒计时器,但我在切换活动时无法实时更新值。每次切换活动后,我只能更新一次值。

举个例子:

活动A -> B(屏幕上默认为0,用户将其更新为10)

B -> A ->(屏幕上为10,用户将其更新为10)

B -> A ->(屏幕上为35,用户将其更新为9000)等等

然而,一旦用户设置了时间,它应该不断更新并倒计时。

我可以通过Runnable在后台更新值并在控制台打印出值,但是我不知道为什么它不会持续地将值传回到先前的活动A(以便它处于最新状态),然后当用户返回B时由A将值传回B。

需要注意的是,当我尝试仅在run()中更新额外信息而不在updateTimerButton()中进行更新时,屏幕上什么都不会改变,只有默认值,但在幕后值正在更新(控制台)。

这是我的代码:

public class CustomTimer extends Activity {

    private final Handler handler = new Handler();

    private Intent intent;
    private Button timerButton;
    private EditText hourValue, minuteValue;

    private long startTime = 0L;
    private long timeInMilliseconds = 0L;
    private long timeSwapBuff = 0L;
    private long updatedTime = 0L;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_timer);

        intent = getIntent();
        hourValue = (EditText) findViewById(R.id.hour_value);
        minuteValue = (EditText) findViewById(R.id.minute_value);
        timerButton = (Button) findViewById(R.id.start_timer_button);

        //avoid grabbing values from hour and minute if they were not passed for some reason
        if(intent.getStringExtra("hourValue") != null)
            hourValue.setText(getIntent().getStringExtra("hourValue"));
        if(intent.getStringExtra("minuteValue") != null)
            minuteValue.setText(getIntent().getStringExtra("minuteValue"));

        setUpHourValue();
        setUpMinuteValue();
        setUpTimerButton();
    }

    private void setUpHourValue(){

        hourValue.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                hourValue.setText(v.getText().toString());
                return false;
            }
        });
    }

    private void setUpMinuteValue(){

        minuteValue.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                minuteValue.setText(v.getText().toString());
                return false;
            }
        });
    }

    private void setUpTimerButton(){

        timerButton.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {

                String hourTime = hourValue.getText().toString();
                String minuteTime = minuteValue.getText().toString();

                //only start the timer if it is not zero
                if (!hourTime.equals("00") || !minuteTime.equals("00")) {
                    System.out.println("starting runnable");
                    startTime = SystemClock.uptimeMillis();
                    handler.postDelayed(updateTimerThread, 0);
                }
                else{
                    System.out.println("time is default\t" + hourTime + "  : " + minuteTime + "************");
                }

                //send the time values back to main
                //this does not constantly update the values, it only updates it once
                intent.putExtra("hourValue", hourTime);
                intent.putExtra("minuteValue", minuteTime);
                setResult(RESULT_OK, intent);
                finish();//go back to the previous page
            }
        });
    }

    private Intent getOuterClassIntent(){
        return intent;
    }

    private Runnable updateTimerThread = new Runnable() {

        //update the time on the screen and constantly pass the values back to main
        public void run() {

            String hourTime = hourValue.getText().toString();
            String minuteTime = minuteValue.getText().toString();

            timeInMilliseconds = SystemClock.uptimeMillis() - startTime;

            updatedTime = timeSwapBuff + timeInMilliseconds;

            int secs = (int) (updatedTime / 1000);
            int mins = secs / 60;
            int hour = mins / 60;
            secs = secs % 60;

            //update the time on screen
            hourValue.setText(Integer.toString(Integer.parseInt(hourTime) - hour));
            minuteValue.setText(Integer.toString(Integer.parseInt(minuteTime) - secs));

            System.out.println("updating time in runnable");
            System.out.println(hourValue.getText().toString()+ " : " + minuteValue.getText().toString());

            //pass the values back to main, but this does NOTHING if I comment out the previous putExtras (above)
            getOuterClassIntent().putExtra("hourValue", hourTime);
            getOuterClassIntent().putExtra("minuteValue", minuteTime);
            setResult(RESULT_OK, getOuterClassIntent());

            handler.postDelayed(this, 0);
        }
    };
}
2个回答

3

如果你需要在多个活动之间共享数据,那么这些数据不应该由任何一个活动独立拥有。创建一个服务,让两个活动启动时都绑定到该服务,并通过 Binder 查询服务获取值。所有对该值的更新都应该在服务中进行。


好的,那么我基本上只需要创建自己的服务,并将大部分来自Runnable的代码(但不包括Runnable本身)放在服务的onStartCommand()中? - bob dylan

0

您可以使用服务来保留倒计时器的值,或者您可以在activity上使用event bus来实时更新值。

EventBus.getDefault().register(your activity);

然后在您的活动A或B中的值更改时发布事件

EventBus.getDefault().post(your value to post);

并重写方法OnEvent(你的数据类型)以获取更新后的值

如需参考,请访问this


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接