Browse files

Added example of AsyncTaskFragment

  • Loading branch information...
1 parent d11e02a commit 52bde9af3fde6c71bdf0bcbaa4da65987caf81f3 @inazaruk committed Jul 30, 2011
View
8 BackgroundThreadFragment/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry kind="lib" path="libs/android-support-v4.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
View
33 BackgroundThreadFragment/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>BackgroundThreadFragment</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
18 BackgroundThreadFragment/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.inazaruk.backgroundthread"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="8" />
+
+ <application android:icon="@drawable/icon" android:label="@string/app_name">
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+</manifest>
View
11 BackgroundThreadFragment/default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-8
View
BIN BackgroundThreadFragment/libs/android-support-v4.jar
Binary file not shown.
View
40 BackgroundThreadFragment/proguard.cfg
@@ -0,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
View
BIN BackgroundThreadFragment/res/drawable-hdpi/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN BackgroundThreadFragment/res/drawable-ldpi/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN BackgroundThreadFragment/res/drawable-mdpi/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
84 BackgroundThreadFragment/res/layout/bkthread.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:text="status: " />
+
+ <TextView
+ android:id="@+id/status"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:text="idle" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:text="progres: " />
+
+ <TextView
+ android:id="@+id/progress"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:text="0" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:text="result: " />
+
+ <TextView
+ android:id="@+id/result"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:text="-" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/start"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:text="start" />
+
+ <Button
+ android:id="@+id/stop"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:text="cancel" />
+
+ </LinearLayout>
+
+</LinearLayout>
View
22 BackgroundThreadFragment/res/layout/main.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/bkthread"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:text="reset"
+ android:onClick="onReset"/>
+
+ </LinearLayout>
+
+</LinearLayout>
View
5 BackgroundThreadFragment/res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="hello">Hello World, MainActivity!</string>
+ <string name="app_name">BackgroundThreadFragment</string>
+</resources>
View
245 BackgroundThreadFragment/src/com/inazaruk/backgroundthread/AsyncTaskFragment.java
@@ -0,0 +1,245 @@
+package com.inazaruk.backgroundthread;
+
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+
+public abstract class AsyncTaskFragment<Params, Progress, Result> extends Fragment
+{
+ static private long sTaskIdCounter = 1;
+ public class FragmentTask extends AsyncTask<Params, Progress, Result>
+ {
+ private final long mId;
+ public FragmentTask()
+ {
+ synchronized (AsyncTaskFragment.class)
+ {
+ mId = sTaskIdCounter++;
+ }
+ }
+
+ @Override
+ protected void onPreExecute()
+ {
+ v(mId+": onPreExecute()");
+ AsyncTaskFragment.this.onPreExecute();
+ }
+
+ @Override
+ protected void onProgressUpdate(Progress... values)
+ {
+ v(mId+": onProgressUpdate()");
+ AsyncTaskFragment.this.onProgressUpdate(values);
+ };
+
+ @Override
+ protected Result doInBackground(Params... params)
+ {
+ v(mId+": doInBackground()");
+ return AsyncTaskFragment.this.doInBackground(params);
+ };
+
+ @Override
+ protected void onPostExecute(Result result)
+ {
+ v(mId+": onPostExecute(): " + result);
+ AsyncTaskFragment.this.onPostExecute(result);
+ };
+
+ @Override
+ protected void onCancelled()
+ {
+ v(mId+": onCancelled()");
+ AsyncTaskFragment.this.onCancelled();
+ }
+
+ protected void publishProgressHelper(Progress...progress)
+ {
+ super.publishProgress(progress);
+ }
+ }
+
+ private Handler mHandler;
+ private FragmentTask mAsyncTask;
+
+ private boolean mVerbose = false;
+ private String mLogTag = getClass().getSimpleName();
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ v("onCreate()");
+ super.onCreate(savedInstanceState);
+
+ /* this allows to survive configuration changes */
+ setRetainInstance(true);
+
+ mHandler = new Handler();
+ mAsyncTask = new FragmentTask();
+ }
+
+ @Override
+ public void onDestroy()
+ {
+ v("onDestroy()");
+ super.onDestroy();
+ mAsyncTask.cancel(true);
+ }
+
+
+ /********************************/
+ /** Helpers **/
+ /********************************/
+
+ protected void runOnUiThread(Runnable runnable)
+ {
+ mHandler.post(runnable);
+ }
+
+ protected Handler getHandler()
+ {
+ return mHandler;
+ }
+
+ /********************************/
+ /** AsyncTask callbacks **/
+ /********************************/
+
+ protected void onPreExecute(){}
+
+ protected void onProgressUpdate(Progress... values){};
+
+ protected abstract Result doInBackground(Params... params);
+
+ protected void onPostExecute(Result result){};
+
+ protected void onCancelled(){}
+
+ protected void publishProgress(Progress...progress)
+ {
+ mAsyncTask.publishProgressHelper(progress);
+ }
+
+ /*********************************/
+ /** AsyncTask functions **/
+ /*********************************/
+
+ public void execute(Params... params)
+ {
+ v("execute()", params.length);
+ mAsyncTask.execute(params);
+ }
+
+ public Result get() throws CancellationException, InterruptedException, ExecutionException
+ {
+ v("get()");
+ return mAsyncTask.get();
+ }
+
+ public Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException,
+ TimeoutException
+ {
+ v("get(timeout, unit)");
+ return mAsyncTask.get(timeout, unit);
+ }
+
+ public boolean cancel(boolean mayInterruptIfRunning)
+ {
+ v("cancel()");
+ return mAsyncTask.cancel(mayInterruptIfRunning);
+ }
+
+ public boolean isCancelled()
+ {
+ return mAsyncTask.isCancelled();
+ }
+
+ public AsyncTask.Status getStatus()
+ {
+ return mAsyncTask.getStatus();
+ }
+
+ public AsyncTask<Params, Progress, Result> getAsyncTask()
+ {
+ return mAsyncTask;
+ }
+
+ /********************************/
+ /** Logs **/
+ /********************************/
+
+ public void setVerbose(boolean verbose)
+ {
+ mVerbose = verbose;
+ }
+
+ public boolean isVerbose()
+ {
+ return mVerbose;
+ }
+
+ public void setLogTag(String tag)
+ {
+ mLogTag = tag;
+ }
+
+ public String getLogTag()
+ {
+ return mLogTag;
+ }
+
+ protected void v(String fmt, Object... objs)
+ {
+ if(mVerbose)
+ {
+ Log.v(mLogTag, String.format(fmt, objs));
+ }
+ }
+
+ protected void v(Throwable ex, String fmt, Object... objs)
+ {
+ if(mVerbose)
+ {
+ Log.v(mLogTag, String.format(fmt, objs), ex);
+ }
+ }
+
+ protected void w(String fmt, Object... objs)
+ {
+ if(mVerbose)
+ {
+ Log.w(mLogTag, String.format(fmt, objs));
+ }
+ }
+
+ protected void w(Throwable ex, String fmt, Object... objs)
+ {
+ if(mVerbose)
+ {
+ Log.w(mLogTag, String.format(fmt, objs), ex);
+ }
+ }
+
+ protected void e(String fmt, Object... objs)
+ {
+ if(mVerbose)
+ {
+ Log.e(mLogTag, String.format(fmt, objs));
+ }
+ }
+
+ protected void e(Throwable ex, String fmt, Object... objs)
+ {
+ if(mVerbose)
+ {
+ Log.e(mLogTag, String.format(fmt, objs), ex);
+ }
+ }
+}
View
130 BackgroundThreadFragment/src/com/inazaruk/backgroundthread/BackgroundThreadFragment.java
@@ -0,0 +1,130 @@
+package com.inazaruk.backgroundthread;
+
+import android.os.Bundle;
+import android.os.AsyncTask.Status;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class BackgroundThreadFragment extends AsyncTaskFragment<Integer, Integer, Integer>
+{
+ TextView mStatus;
+ TextView mProgress;
+ TextView mResult;
+ Button mStart;
+ Button mStop;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ setVerbose(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ View view = inflater.inflate(R.layout.bkthread, container, false);
+
+ mStatus = (TextView)view.findViewById(R.id.status);
+ mProgress = (TextView)view.findViewById(R.id.progress);
+ mResult = (TextView)view.findViewById(R.id.result);
+ mStart = (Button)view.findViewById(R.id.start);
+ mStop = (Button)view.findViewById(R.id.stop);
+
+ mStart.setEnabled(getStatus() == Status.PENDING);
+ mStop.setEnabled(getStatus() != Status.PENDING && !isCancelled());
+
+ mStart.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ mStart.setEnabled(false);
+ mStop.setEnabled(true);
+ execute(100, 100);
+ }
+ });
+
+ mStop.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ mStop.setEnabled(false);
+ cancel(true);
+ }
+ });
+
+ return view;
+ }
+
+ @Override
+ protected void onPreExecute()
+ {
+ super.onPreExecute();
+ mStatus.setText("starting...");
+ mProgress.setText("-");
+ mResult.setText("-");
+ }
+
+ @Override
+ protected void onProgressUpdate(Integer... values)
+ {
+ mProgress.setText(values[0].toString());
+ }
+
+ @Override
+ protected Integer doInBackground(Integer... params)
+ {
+ runOnUiThread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ mStatus.setText("running");
+ }
+ });
+
+ int counter = params[0];
+ int timeout = params[1];
+
+ int done = 0;
+ for(int i = 0; i < counter && !isCancelled(); i++)
+ {
+ v("counter: "+i);
+ done++;
+ publishProgress(i);
+ try
+ {
+ Thread.sleep(timeout);
+ }
+ catch(InterruptedException ex)
+ {
+ e(ex, "sleep interruption");
+ }
+ }
+
+ return done;
+ }
+
+ @Override
+ protected void onPostExecute(Integer result)
+ {
+ mStatus.setText("completed");
+ mResult.setText(result.toString());
+ }
+
+ @Override
+ protected void onCancelled()
+ {
+ mStatus.setText("cancelled");
+ mResult.setText("x");
+ }
+
+
+}
View
37 BackgroundThreadFragment/src/com/inazaruk/backgroundthread/MainActivity.java
@@ -0,0 +1,37 @@
+package com.inazaruk.backgroundthread;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.view.View;
+
+public class MainActivity extends FragmentActivity
+{
+ BackgroundThreadFragment mBkthreadFragment;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ FragmentManager manager = getSupportFragmentManager();
+ FragmentTransaction transaction = manager.beginTransaction();
+ mBkthreadFragment = new BackgroundThreadFragment();
+ transaction.add(R.id.bkthread, mBkthreadFragment);
+ transaction.commit();
+ }
+
+ public void onReset(View v)
+ {
+ FragmentManager manager = getSupportFragmentManager();
+ FragmentTransaction transaction = manager.beginTransaction();
+ transaction.remove(mBkthreadFragment);
+
+ mBkthreadFragment = new BackgroundThreadFragment();
+ transaction.add(R.id.bkthread, mBkthreadFragment);
+
+ transaction.commit();
+ }
+}

0 comments on commit 52bde9a

Please sign in to comment.