simple.android.compat.SimpleFragmentActivity.java Source code

Java tutorial

Introduction

Here is the source code for simple.android.compat.SimpleFragmentActivity.java

Source

/** 
 * Copyright 2011 Gavin Saunders
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package simple.android.compat;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;

import simple.android.Command;
import simple.android.CommandProcessor;
import simple.android.UIWidget;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;

public abstract class SimpleFragmentActivity<T extends Serializable> extends FragmentActivity {

    private SimpleActivityState<T> mState;
    private CommandProcessor mCommandProcessor;

    public static class SimpleActivityState<T> implements Serializable {

        private static final long serialVersionUID = -3547400596204942327L;
        public T userData;
        private ArrayList<AsyncTask<Void, Void, Void>> mAsyncTasks;

        public ArrayList<AsyncTask<Void, Void, Void>> getAsyncTasks() {
            if (mAsyncTasks == null) {
                mAsyncTasks = new ArrayList<AsyncTask<Void, Void, Void>>();
            }
            return mAsyncTasks;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            mState = (SimpleActivityState<T>) savedInstanceState.getSerializable("state");
        }
        if (mState == null) {
            mState = new SimpleActivityState<T>();
            mState.userData = onNewState();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        onRestoreState(mState.userData);
    }

    @Override
    public void setContentView(int layoutResID) {
        super.setContentView(layoutResID);
        Class<?> c = getClass();
        initUIWidgets(c);
    }

    private void initUIWidgets(Class<?> c) {
        //Log.i("SysMon4A", "---- initUIWidgets ----");
        Field[] fields = c.getDeclaredFields();
        for (Field field : fields) {
            UIWidget a = field.getAnnotation(UIWidget.class);
            if (a != null) {
                //Log.i("SysMon4A", "---- initUIWidgets ----: found field " + a);
                field.setAccessible(true);
                View view = findViewById(a.id());
                try {
                    field.set(this, view);
                } catch (IllegalArgumentException e) {
                    Log.e("SysMon4A", "Failed to set @UIWidget", e);
                } catch (IllegalAccessException e) {
                    Log.e("SysMon4A", "Failed to set @UIWidget", e);
                } catch (ClassCastException e) {
                    Log.e("SysMon4A", "Failed to set @UIWidget", e);
                }
            }
        }
        Class<?> sc = c.getSuperclass();
        if (!SimpleFragmentActivity.class.equals(sc)) {
            initUIWidgets(sc);
        }

    }

    protected CommandProcessor getCommandProcessor() {
        if (mCommandProcessor == null) {
            mCommandProcessor = new CommandProcessor() {
                @Override
                public void executeAt(Date time, Command command) {
                }

                @Override
                public void executeAsync(Command command) {
                    executeAsyncCommand(command);
                }

                @Override
                public void cancel(Command command) {
                    cancelCommand(command);
                }
            };
        }
        return mCommandProcessor;
    }

    /**
     * TODO: fail if command already executing. Should create new instance of command
     */
    private void executeAsyncCommand(final Command command) {
        final AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                Log.i("SimpleAndroid", command + " executing....");
                command.execute();
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                mState.getAsyncTasks().remove(this);
                Log.i("SimpleAndroid", command + " completed");
            }

            @Override
            protected void onCancelled() {
                command.cancel();
                mState.getAsyncTasks().remove(this);
                Log.i("SimpleAndroid", command + " cancelled");
            }
        };
        mState.getAsyncTasks().add(asyncTask);
        asyncTask.execute();
    }

    protected void cancelCommand(final Command command) {
        throw new RuntimeException("Not implemented!");
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putSerializable("state", mState);
    }

    /**
     * TODO: Does this need to be Serializable?
     */
    protected abstract T onNewState();

    protected abstract void onRestoreState(T state);

    protected T getState() {
        return mState.userData;
    }

    @Override
    protected void onDestroy() {
        if (isFinishing()) {
            ArrayList<AsyncTask<Void, Void, Void>> tasks = mState.getAsyncTasks();
            for (AsyncTask<Void, Void, Void> asyncTask : tasks) {
                asyncTask.cancel(false); // TODO: should this be true?
            }
        }
        super.onDestroy();
    }
}