যদিও অ্যান্ড্রয়েড অপারেটিং সিস্টেমে এমন কোনও ব্যবস্থা নেই যা যথেষ্ট পরিমাণে আপনার সমস্যার সমাধান করে বলে মনে হয় আমি বিশ্বাস করি যে এই প্যাটার্নটি কার্যকরভাবে বাস্তবায়ন করতে তুলনামূলকভাবে সহজ সরবরাহ করে।
নিম্নলিখিত ক্লাসটি এমন একটি মোড়কের চারপাশে android.os.Handler
যা কোনও ক্রিয়াকলাপ বন্ধ হয়ে যাওয়ার পরে বার্তাগুলি বাফার করে এবং পুনরায় শুরুতে এগুলিকে খেলায়।
আপনার যে কোনও কোড রয়েছে তা নিশ্চিত করুন যা অবিচ্ছিন্নভাবে একটি খণ্ডের স্থিতি পরিবর্তন করে (যেমন প্রতিশ্রুতিবদ্ধ, খারিজ) কেবলমাত্র হ্যান্ডলারের কোনও বার্তা থেকে আহ্বান করা হয়েছে।
আপনার হ্যান্ডলারটি PauseHandler
ক্লাস থেকে বের করুন ।
যখনই আপনার ক্রিয়াকলাপ onPause()
কল PauseHandler.pause()
এবং onResume()
কল আসে PauseHandler.resume()
।
আপনার হ্যান্ডলারের বাস্তবায়নটি এর handleMessage()
সাথে প্রতিস্থাপন করুন processMessage()
।
একটি সাধারণ বাস্তবায়ন সরবরাহ করুন storeMessage()
যা সর্বদা ফিরে আসে true
।
public abstract class PauseHandler extends Handler {
final Vector<Message> messageQueueBuffer = new Vector<Message>();
private boolean paused;
final public void resume() {
paused = false;
while (messageQueueBuffer.size() > 0) {
final Message msg = messageQueueBuffer.elementAt(0);
messageQueueBuffer.removeElementAt(0);
sendMessage(msg);
}
}
final public void pause() {
paused = true;
}
protected abstract boolean storeMessage(Message message);
protected abstract void processMessage(Message message);
@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);
}
}
}
PausedHandler
ক্লাসটি কীভাবে ব্যবহার করা যায় তার নীচে একটি সাধারণ উদাহরণ দেওয়া হল ।
একটি বোতামের ক্লিকে একটি বিলম্বিত বার্তা হ্যান্ডলারের কাছে প্রেরণ করা হয়।
হ্যান্ডলার যখন বার্তাটি পায় (ইউআই থ্রেডে) এটি প্রদর্শিত হয় DialogFragment
।
PausedHandler
ক্লাসটি যদি ব্যবহার না করা হয় তবে ডায়ালগটি আরম্ভ করার জন্য টেস্ট বোতামটি চাপার পরে যদি হোম বোতামটি টিপানো হয় তবে যদি অবৈধ স্ট্যাটেক্সেপশনটি প্রদর্শিত হয়।
public class FragmentTestActivity extends Activity {
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";
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);
}
}
final static int DELAY = 2000;
@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) {
fragment.handler.sendMessageDelayed(
fragment.handler.obtainMessage(MSG_WHAT, MSG_SHOW_DIALOG, value++),
DELAY);
}
}
});
}
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
}
public static class TestDialog extends DialogFragment {
int value;
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;
}
}
static class ConcreteTestHandler extends PauseHandler {
protected Activity activity;
final void setActivity(Activity activity) {
this.activity = activity;
}
@Override
final protected boolean storeMessage(Message message) {
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);
dialog.show(fm, TestDialog.TAG);
break;
}
break;
}
}
}
}
}
ক্রিয়াকলাপটি থেমে থাকা সত্ত্বেও কোনও বার্তা তত্ক্ষণাত প্রসেস করা উচিত ক্ষেত্রে আমি ক্লাসে একটি storeMessage()
পদ্ধতি যুক্ত করেছি PausedHandler
। যদি কোনও বার্তা পরিচালনা করা হয় তবে মিথ্যাটি ফিরিয়ে দেওয়া উচিত এবং বার্তাটি ফেলে দেওয়া হবে।