Last active
December 26, 2015 09:49
-
-
Save tomoattori/7131930 to your computer and use it in GitHub Desktop.
ProgressDialogからキャンセル可能なAsyncTask(未完成)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ・AsyncTaskで処理を実行 | |
// ・ProgressDialogで進行状況を表示 | |
// ・途中キャンセル可能 | |
// | |
// という実装をしたいのだけどどうにもうまく行ってないコード。 | |
// (普通に使う分には問題ないけどonPause時に例外を吐いて落ちる) | |
package com.example.cancelasyncprogress; | |
import android.os.AsyncTask; | |
import android.os.Bundle; | |
import android.view.View; | |
import android.view.View.OnClickListener; | |
import android.widget.Button; | |
import android.widget.Toast; | |
import android.app.Activity; | |
import android.app.Dialog; | |
import android.app.DialogFragment; | |
import android.app.ProgressDialog; | |
import android.content.DialogInterface; | |
import java.io.Serializable; | |
public class MainActivity extends Activity { | |
Activity activity = this; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
// タスクを実行するボタンを定義 | |
Button button = (Button) findViewById(R.id.button1); | |
button.setOnClickListener(new OnClickListener() { | |
@Override | |
public void onClick(View arg0) { | |
// AsyncTaskの実行 | |
CancellableAsyncTask task = new CancellableAsyncTask(); | |
task.execute(); | |
} | |
}); | |
} | |
// ProgressDialogを出しつつキャンセル可能なAsyncTask(目標) | |
public class CancellableAsyncTask extends AsyncTask<Void, Integer, Boolean> { | |
private ProcessingDialog dialog; | |
@Override | |
protected void onPreExecute() { | |
// ProgressDialogに設定するパラメータの設定 | |
Bundle argsD = new Bundle(); | |
argsD.putString("title", "実行中"); | |
argsD.putString("message", "しばらくお待ちください"); | |
argsD.putSerializable("listener", new ProcessingDialog.CancelListener() { | |
private static final long serialVersionUID = 1L; | |
@Override | |
public void canceled(DialogInterface _interface) { | |
Toast.makeText(activity, "タスクをキャンセルします", Toast.LENGTH_SHORT).show(); | |
// BACKキーでDialogを消す際にTaskを停止。 | |
cancel(true); | |
} | |
}); | |
// ProgressDialogを表示する | |
dialog = new ProcessingDialog(); | |
dialog.setArguments(argsD); | |
dialog.show(activity.getFragmentManager(), "setdata"); | |
} | |
@Override | |
protected Boolean doInBackground(Void... args) { | |
// 1秒ごとにProgressDialogを更新するだけの簡単なお仕事 | |
int count = 0; | |
while (count < 10) { | |
try { | |
Thread.sleep(1000); | |
} catch (InterruptedException e) { | |
} | |
publishProgress(++count); | |
} | |
return true; | |
} | |
@Override | |
protected void onProgressUpdate(Integer... values) { | |
dialog.updateProgress(values[0]); | |
} | |
@Override | |
protected void onPostExecute(Boolean result) { | |
dialog.getDialog().dismiss(); | |
Toast.makeText(activity, "タスクが終了しました", Toast.LENGTH_SHORT).show(); | |
} | |
@Override | |
protected void onCancelled() { | |
Toast.makeText(activity, "キャンセルされました", Toast.LENGTH_SHORT).show(); | |
} | |
} | |
// AsyncTaskから生成されるProgressDialog(を生成するDialogFragment) | |
public static class ProcessingDialog extends DialogFragment { | |
// キャンセルリスナー用インターフェースの定義 | |
public interface CancelListener extends Serializable { | |
public void canceled(DialogInterface di); | |
} | |
// Bundleで渡されるリスナーの保管場所 | |
private CancelListener listener = null; | |
// ProgressDialog本体 | |
private ProgressDialog progressDialog; | |
@Override | |
public Dialog onCreateDialog(Bundle savedInstanceState) { | |
// Bundleからリスナーを取得 | |
listener = (CancelListener) getArguments().getSerializable("listener"); | |
// ダイアログが生成ずみの場合はそれを返す | |
if (progressDialog != null) { | |
return progressDialog; | |
} | |
// ダイアログをキャンセル可能にする | |
setCancelable(true); | |
// ダイアログを生成する | |
progressDialog = new ProgressDialog(getActivity()); | |
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); | |
progressDialog.setTitle(getArguments().getString("title")); | |
progressDialog.setMessage(getArguments().getString("message")); | |
progressDialog.setMax(10); | |
return progressDialog; | |
} | |
// キャンセルリスナーの実装(?) | |
@Override | |
public void onCancel(DialogInterface di) { | |
listener.canceled(di); | |
} | |
// プログレスバーの更新 | |
public void updateProgress(int value) { | |
if (progressDialog != null) { | |
progressDialog.setProgress(value); | |
} | |
} | |
@Override | |
public void onDestroy() { | |
super.onDestroy(); | |
progressDialog = null; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
E/AndroidRuntime( 9211): FATAL EXCEPTION: main | |
E/AndroidRuntime( 9211): java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.example.cancelasyncprogress.MainActivity$CancellableAsyncTask$1) | |
E/AndroidRuntime( 9211): at android.os.Parcel.writeSerializable(Parcel.java:1279) | |
E/AndroidRuntime( 9211): at android.os.Parcel.writeValue(Parcel.java:1233) | |
E/AndroidRuntime( 9211): at android.os.Parcel.writeMapInternal(Parcel.java:591) | |
E/AndroidRuntime( 9211): at android.os.Bundle.writeToParcel(Bundle.java:1627) | |
E/AndroidRuntime( 9211): at android.os.Parcel.writeBundle(Parcel.java:605) | |
E/AndroidRuntime( 9211): at android.app.FragmentState.writeToParcel(Fragment.java:131) | |
E/AndroidRuntime( 9211): at android.os.Parcel.writeTypedArray(Parcel.java:1102) | |
E/AndroidRuntime( 9211): at android.app.FragmentManagerState.writeToParcel(FragmentManager.java:371) | |
E/AndroidRuntime( 9211): at android.os.Parcel.writeParcelable(Parcel.java:1254) | |
E/AndroidRuntime( 9211): at android.os.Parcel.writeValue(Parcel.java:1173) | |
E/AndroidRuntime( 9211): at android.os.Parcel.writeMapInternal(Parcel.java:591) | |
E/AndroidRuntime( 9211): at android.os.Bundle.writeToParcel(Bundle.java:1627) | |
E/AndroidRuntime( 9211): at android.os.Parcel.writeBundle(Parcel.java:605) | |
E/AndroidRuntime( 9211): at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2252) | |
E/AndroidRuntime( 9211): at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3052) | |
E/AndroidRuntime( 9211): at android.os.Handler.handleCallback(Handler.java:725) | |
E/AndroidRuntime( 9211): at android.os.Handler.dispatchMessage(Handler.java:92) | |
E/AndroidRuntime( 9211): at android.os.Looper.loop(Looper.java:137) | |
E/AndroidRuntime( 9211): at android.app.ActivityThread.main(ActivityThread.java:5041) | |
E/AndroidRuntime( 9211): at java.lang.reflect.Method.invokeNative(Native Method) | |
E/AndroidRuntime( 9211): at java.lang.reflect.Method.invoke(Method.java:511) | |
E/AndroidRuntime( 9211): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) | |
E/AndroidRuntime( 9211): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) | |
E/AndroidRuntime( 9211): at dalvik.system.NativeStart.main(Native Method) | |
E/AndroidRuntime( 9211): Caused by: java.io.NotSerializableException: com.example.cancelasyncprogress.MainActivity$CancellableAsyncTask | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1364) | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671) | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517) | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481) | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979) | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368) | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074) | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404) | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671) | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517) | |
E/AndroidRuntime( 9211): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481) | |
E/AndroidRuntime( 9211): at android.os.Parcel.writeSerializable(Parcel.java:1274) | |
E/AndroidRuntime( 9211): ... 23 more | |
W/ActivityManager( 391): Force finishing activity com.example.cancelasyncprogress/.MainActivity |
putSerializableしたオブジェクトのonPause越えはヤバイ、なんて情報も見つかるのですが、この辺関係あるのかしら?
Bundle の putSerializable() で List や Map や CharSequence を実装したオブジェクトを渡すのはやばい - gae+eyoの日記
http://d.hatena.ne.jp/gae+eyo/20130801/1375339519
画面の向きを変えたりとか - らくがき
http://www.wildtree.jp/~araki/rakugaki/2011/05/post-2431.html
たまたま同じようなことを考えていたmstsskさんの実装。
これがonPauseを越えられたのかどうかちょっと気になる。
FragmentからActivityにコールバックする手段の一つとして、listenerをserializableにしてargmentsに詰めてしまうやり方を試してみた。
https://gist.github.com/mstssk/7123411
相手がActivityなコールバックの場合はyanzm先生の実装が一番いいみたいなのですが、今回やりたい事(AsyncTaskのキャンセル)にも応用できるのかしら?
Y.A.M の 雑記帳: Fragment から Activity にコールバックする方法
http://y-anz-m.blogspot.jp/2012/06/fragment-activity.html
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
知識の元ネタは以下のサイト。(ありがとうございます)
AsyncTaskと仲良くなろう:バックグラウンド処理とキャンセル - ReDo
http://greety.sakura.ne.jp/redo/2011/02/asynctask.html
画面回転、キャンセル対応のProgress DialogFragment-Oboe吹きプログラマの黙示録
http://blog.zaq.ne.jp/oboe2uran/article/877/