PJL*_*PJL 98 android android-fragments
基本上我Handler
在我的消息中Fragment
收到一堆消息,这些消息可能导致对话框被解除或显示.
当应用程序进入后台时,我得到了一个,onPause
但仍然可以像我们期望的那样得到我的消息.但是,因为我正在使用片段,所以我不能只关闭并显示对话框,因为这将导致一个IllegalStateException
.
我不能只是解雇或取消允许国家损失.
鉴于我有一个Handler
我想知道是否有一个推荐的方法,我应该如何在暂停状态下处理消息.
我正在考虑的一个可能的解决方案是记录暂停时播放的消息并将其播放回来onResume
.这有点令人不满意,我认为框架中必须有一些东西可以更优雅地处理这个问题.
qui*_*raw 166
虽然Android操作系统似乎没有足够解决您问题的机制,但我相信这种模式确实提供了一种相对简单的实现变通方法.
以下类是一个包装器,android.os.Handler
它在暂停活动时缓冲消息并在恢复时播放它们.
确保只有处理程序中的消息调用任何异步更改片段状态的代码(例如,commit,dismiss).
从PauseHandler
类中派生你的处理程序.
每当您的活动接到onPause()
电话PauseHandler.pause()
和onResume()
电话时PauseHandler.resume()
.
更换你的处理程序的执行handleMessage()
与processMessage()
.
提供一个storeMessage()
总是返回的简单实现true
.
/**
* Message Handler class that supports buffering up of messages when the
* activity is paused i.e. in the background.
*/
public abstract class PauseHandler extends Handler {
/**
* Message Queue Buffer
*/
final Vector<Message> messageQueueBuffer = new Vector<Message>();
/**
* Flag indicating the pause state
*/
private boolean paused;
/**
* Resume the handler
*/
final public void resume() {
paused = false;
while (messageQueueBuffer.size() > 0) {
final Message msg = messageQueueBuffer.elementAt(0);
messageQueueBuffer.removeElementAt(0);
sendMessage(msg);
}
}
/**
* Pause the handler
*/
final public void pause() {
paused = true;
}
/**
* Notification that the message is about to be stored as the activity is
* paused. If not handled the message will be saved and replayed when the
* activity resumes.
*
* @param message
* the message which optional can be handled
* @return true if the message is to be stored
*/
protected abstract boolean storeMessage(Message message);
/**
* Notification message to be processed. This will either be directly from
* handleMessage or played back from a saved message when the activity was
* paused.
*
* @param message
* the message to be handled
*/
protected abstract void processMessage(Message message);
/** {@inheritDoc} */
@Override
final public void handleMessage(Message msg) {
if (paused) {
if (storeMessage(msg)) {
Message msgCopy = new Message();
msgCopy.copyFrom(msg);
messageQueueBuffer.add(msgCopy);
}
} else {
processMessage(msg);
}
}
}
Run Code Online (Sandbox Code Playgroud)
下面是一个如何使用PausedHandler
类的简单示例.
在单击按钮时,延迟消息将发送到处理程序.
当处理程序收到消息时(在UI线程上),它会显示一个DialogFragment
.
如果PausedHandler
未使用该类,则在按下测试按钮以启动对话框后按下主页按钮时将显示IllegalStateException.
public class FragmentTestActivity extends Activity {
/**
* Used for "what" parameter to handler messages
*/
final static int MSG_WHAT = ('F' << 16) + ('T' << 8) + 'A';
final static int MSG_SHOW_DIALOG = 1;
int value = 1;
final static class State extends Fragment {
static final String TAG = "State";
/**
* Handler for this activity
*/
public ConcreteTestHandler handler = new ConcreteTestHandler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onResume() {
super.onResume();
handler.setActivity(getActivity());
handler.resume();
}
@Override
public void onPause() {
super.onPause();
handler.pause();
}
public void onDestroy() {
super.onDestroy();
handler.setActivity(null);
}
}
/**
* 2 second delay
*/
final static int DELAY = 2000;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (savedInstanceState == null) {
final Fragment state = new State();
final FragmentManager fm = getFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
ft.add(state, State.TAG);
ft.commit();
}
final Button button = (Button) findViewById(R.id.popup);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final FragmentManager fm = getFragmentManager();
State fragment = (State) fm.findFragmentByTag(State.TAG);
if (fragment != null) {
// Send a message with a delay onto the message looper
fragment.handler.sendMessageDelayed(
fragment.handler.obtainMessage(MSG_WHAT, MSG_SHOW_DIALOG, value++),
DELAY);
}
}
});
}
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
}
/**
* Simple test dialog fragment
*/
public static class TestDialog extends DialogFragment {
int value;
/**
* Fragment Tag
*/
final static String TAG = "TestDialog";
public TestDialog() {
}
public TestDialog(int value) {
this.value = value;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View inflatedView = inflater.inflate(R.layout.dialog, container, false);
TextView text = (TextView) inflatedView.findViewById(R.id.count);
text.setText(getString(R.string.count, value));
return inflatedView;
}
}
/**
* Message Handler class that supports buffering up of messages when the
* activity is paused i.e. in the background.
*/
static class ConcreteTestHandler extends PauseHandler {
/**
* Activity instance
*/
protected Activity activity;
/**
* Set the activity associated with the handler
*
* @param activity
* the activity to set
*/
final void setActivity(Activity activity) {
this.activity = activity;
}
@Override
final protected boolean storeMessage(Message message) {
// All messages are stored by default
return true;
};
@Override
final protected void processMessage(Message msg) {
final Activity activity = this.activity;
if (activity != null) {
switch (msg.what) {
case MSG_WHAT:
switch (msg.arg1) {
case MSG_SHOW_DIALOG:
final FragmentManager fm = activity.getFragmentManager();
final TestDialog dialog = new TestDialog(msg.arg2);
// We are on the UI thread so display the dialog
// fragment
dialog.show(fm, TestDialog.TAG);
break;
}
break;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我已经storeMessage()
为PausedHandler
该类添加了一个方法,以防即使在活动暂停时也应该立即处理任何消息.如果处理了消息,则应返回false并丢弃该消息.
Wil*_*iam 10
一个稍微简单的quickdraw版本的优秀PauseHandler是
/**
* Message Handler class that supports buffering up of messages when the activity is paused i.e. in the background.
*/
public abstract class PauseHandler extends Handler {
/**
* Message Queue Buffer
*/
private final List<Message> messageQueueBuffer = Collections.synchronizedList(new ArrayList<Message>());
/**
* Flag indicating the pause state
*/
private Activity activity;
/**
* Resume the handler.
*/
public final synchronized void resume(Activity activity) {
this.activity = activity;
while (messageQueueBuffer.size() > 0) {
final Message msg = messageQueueBuffer.get(0);
messageQueueBuffer.remove(0);
sendMessage(msg);
}
}
/**
* Pause the handler.
*/
public final synchronized void pause() {
activity = null;
}
/**
* Store the message if we have been paused, otherwise handle it now.
*
* @param msg Message to handle.
*/
@Override
public final synchronized void handleMessage(Message msg) {
if (activity == null) {
final Message msgCopy = new Message();
msgCopy.copyFrom(msg);
messageQueueBuffer.add(msgCopy);
} else {
processMessage(activity, msg);
}
}
/**
* Notification message to be processed. This will either be directly from
* handleMessage or played back from a saved message when the activity was
* paused.
*
* @param activity Activity owning this Handler that isn't currently paused.
* @param message Message to be handled
*/
protected abstract void processMessage(Activity activity, Message message);
}
Run Code Online (Sandbox Code Playgroud)
它确实假设您始终要存储脱机消息以进行重播.并提供Activity作为输入,#processMessages
因此您无需在子类中对其进行管理.
归档时间: |
|
查看次数: |
69442 次 |
最近记录: |