post 可以在旋转屏幕时丢失吗?
Can a post be lost while rotating screen?
有没有可能当我点击按钮然后等待一段时间(~5 秒)后旋转屏幕 post 可能会被错过,因为 activity 没有设法重新- 及时注册?
我相信我已经做到了。但这就像 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;
}
}
}
您的 Activity 会在您旋转设备时重新创建。您可以像这样设置清单属性。 android:configChanges="orientation|keyboardHidden|screenSize"
您需要 subsribe/unsubscribe 监听器不在 onStart
和 onStop
中,而是在 onCreate
和 onDestroy
中。此外,post main
线程中的事件。在这种情况下,不会有间隙,如果 recteated
new activity 将收到事件
代码有可能 Activity 由于娱乐而错过了事件,但是如果这是一个问题,那么您很可能应该将事件发布为 sticky
:
Some events carry information that is of interest after the event is
posted. For example, an event signals that some initialization is
complete. Or if you have some sensor or location data and you want to
hold on the most recent values. Instead of implementing your own
caching, you can use sticky events. EventBus keeps the last sticky
event of a certain type in memory. The sticky event can be delivered
to subscribers or queried explicitly. Thus, you don’t need any special
logic to consider already available data.
http://greenrobot.org/eventbus/documentation/configuration/sticky-events/
此外,一些人建议将注册处理从 onStart
/onStop
移动到 onCreate
/onDestroy
。我认为这是个坏主意 - 如果你在后台,你通常不关心事件,因此我还建议将 reg/unreg 代码移动到 onResume
/onPause
。
您需要做的是使用 onSaveInstanceState() 方法重新创建 activity。
保存你的Activity状态
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);
}
恢复你的Activity状态
@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
}
...
}
有没有可能当我点击按钮然后等待一段时间(~5 秒)后旋转屏幕 post 可能会被错过,因为 activity 没有设法重新- 及时注册? 我相信我已经做到了。但这就像 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;
}
}
}
您的 Activity 会在您旋转设备时重新创建。您可以像这样设置清单属性。 android:configChanges="orientation|keyboardHidden|screenSize"
您需要 subsribe/unsubscribe 监听器不在 onStart
和 onStop
中,而是在 onCreate
和 onDestroy
中。此外,post main
线程中的事件。在这种情况下,不会有间隙,如果 recteated
代码有可能 Activity 由于娱乐而错过了事件,但是如果这是一个问题,那么您很可能应该将事件发布为 sticky
:
Some events carry information that is of interest after the event is posted. For example, an event signals that some initialization is complete. Or if you have some sensor or location data and you want to hold on the most recent values. Instead of implementing your own caching, you can use sticky events. EventBus keeps the last sticky event of a certain type in memory. The sticky event can be delivered to subscribers or queried explicitly. Thus, you don’t need any special logic to consider already available data.
http://greenrobot.org/eventbus/documentation/configuration/sticky-events/
此外,一些人建议将注册处理从 onStart
/onStop
移动到 onCreate
/onDestroy
。我认为这是个坏主意 - 如果你在后台,你通常不关心事件,因此我还建议将 reg/unreg 代码移动到 onResume
/onPause
。
您需要做的是使用 onSaveInstanceState() 方法重新创建 activity。
保存你的Activity状态
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);
}
恢复你的Activity状态
@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
}
...
}