旋转屏幕时可能会丢失帖子吗?

时间:2016-05-10 07:35:00

标签: android greenrobot-eventbus

当我点击按钮然后等待一段时间(约5秒)后旋转屏幕可能会错过帖子,因为活动没有设法及时重新注册? 我相信我已经成功实现了这一目标。但它似乎是50次尝试中的1次:)

import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends BaseActivity {

    @BindView(R.id.post)
    Button mPost;

    @BindView(R.id.result)
    TextView mResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }

    @OnClick(R.id.post)
    void onPostClick() {

        HandlerThread handlerThread = new HandlerThread("MyThread");
        handlerThread.start();
        Handler handler = new Handler(handlerThread.getLooper());

        handler.post(new Runnable() {
            @Override
            public void run() {
                Log.e(TAG, Thread.currentThread().getName());
                try {
                    Thread.sleep(5000);
                    EventBus.getDefault().post(new MyObject("wow"));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });


    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onResult(MyObject object) {
        Log.e(TAG, "POST " + object);
    }

    static class MyObject {
        String val;

        public MyObject(String val) {
            this.val = val;
        }

        @Override
        public String toString() {
            return val;
        }
    }
}

4 个答案:

答案 0 :(得分:1)

由于娱乐活动,活动代码可能会错过活动,但如果这是一个问题,那么您很可能应该将您的活动发布为sticky

  

某些事件包含事件发生后感兴趣的信息   发布。例如,事件表示某些初始化是   完成。或者,如果您有一些传感器或位置数据,并且您想要   坚持最新的价值观。而不是实现自己的   缓存,您可以使用粘性事件。 EventBus保持最后的粘性   记忆中某种类型的事件。粘性事件可以传递   订阅者或明确查询。因此,您不需要任何特殊的   考虑已有数据的逻辑。

http://greenrobot.org/eventbus/documentation/configuration/sticky-events/

此外,有些人建议将注册处理从onStart / onStop移至onCreate / onDestroy。我认为这是个坏主意 - 如果你在后台,你通常不关心这些事件,因此我也建议将注册/取消注册代码转移到onResume / onPause

答案 1 :(得分:0)

旋转设备时,您的活动会重新创建。您可以设置清单属性。 android:configChanges="orientation|keyboardHidden|screenSize"

答案 2 :(得分:0)

您需要做的是使用onSaveInstanceState()方法重新创建活动。

保存您的活动状态

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);

// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}

恢复您的活动状态

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first

// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
    // Restore value of members from saved state
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
    mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
    // Probably initialize members with default values for a new instance
}
...
}

答案 3 :(得分:-1)

您需要在onStartonStop中,但在onCreateonDestroy中,不必订阅/取消订阅收听者。另外,在main主题中发布事件。在这种情况下,不会有差距,如果重新安排,新活动将收到该事件