zoukankan      html  css  js  c++  java
  • 预加载(学习一)

    listview尝试做个demo更加了解使用预加载 优化app性能:

    见代码:

    闪屏页:

    package com.example.myusertask;

    import android.app.Activity;
    import android.content.Intent;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.os.Handler;
    import android.widget.Toast;

    public class MainActivity extends Activity {

    private Handler handler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    for(int i = 0; i < 15; i++) {//预读15张图片
    ReadImgTask task = new ReadImgTask();
    task.execute(String.valueOf(i));
    }
    Toast.makeText(getApplicationContext(), "PreReading...", Toast.LENGTH_LONG).show();
    handler.postDelayed(new Runnable() {

    @Override
    public void run() {
    startActivity(new Intent(MainActivity.this, MyActivity.class));//启动MainActivity

    finish();
    }
    }, 3000);//显示三秒钟的欢迎界面
    }

    class ReadImgTask extends PreReadTask<String, Void, Void> {

    @Override
    protected Void doInBackground(String... arg0) {
    try {
    Thread.sleep(200);//模拟网络延时
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    Data.putData(arg0[0], BitmapFactory.decodeResource(getResources(), R.drawable.cool));//把预读的数据放到hashmap中
    return null;
    }

    }
    }

    加载页:

    package com.example.myusertask;

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;

    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ImageView;
    import android.widget.ListView;
    import android.widget.TextView;

    public class MyActivity extends Activity {
    private ListView mListView;
    private List<HashMap<String, Object>> mData;

    private BaseAdapter mAdapter;


    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);

    mListView = (ListView) findViewById(R.id.listview);
    mData = new ArrayList<HashMap<String,Object>>();
    mAdapter = new CustomAdapter();

    mListView.setAdapter(mAdapter);
    for(int i = 0; i < 100; i++) {//初始化100项数据
    HashMap data = new HashMap<String, Object>();
    data.put("title", "title" + i);
    mData.add(data);
    }
    }




    class CustomAdapter extends BaseAdapter {


    CustomAdapter() {

    }

    @Override
    public int getCount() {
    return mData.size();
    }

    @Override
    public Object getItem(int position) {
    return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
    return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    ViewHolder vh;
    if(view == null) {
    view = LayoutInflater.from(MyActivity.this).inflate(R.layout.list_item, null);
    vh = new ViewHolder();
    vh.tv = (TextView) view.findViewById(R.id.textView);
    vh.iv = (ImageView) view.findViewById(R.id.imageView);
    view.setTag(vh);
    }
    vh = (ViewHolder) view.getTag();
    vh.tv.setText((String) mData.get(position).get("title"));
    Bitmap bitmap = (Bitmap) mData.get(position).get("pic");
    if(bitmap != null) {
    vh.iv.setImageBitmap(bitmap);
    }
    else {
    vh.iv.setImageBitmap(null);
    }

    AsyncTask task = (AsyncTask) mData.get(position).get("task");
    if(task == null || task.isCancelled()) {
    //mData.get(position).put("task", new GetItemImageTask(position).execute(null));//启动线程异步获取图片
    mData.get(position).put("task", new GetItemImageTask(position).execute());
    }

    return view;
    }



    }

    static class ViewHolder {
    TextView tv;
    ImageView iv;
    }

    class GetItemImageTask extends AsyncTask<Void, Void, Void> {

    int id;

    GetItemImageTask(int id) {
    this.id = id;
    }

    @Override
    protected Void doInBackground(Void... params) {

    Bitmap bm = (Bitmap) Data.getData(String.valueOf(id));
    if(bm != null) {//如果hashmap中已经有数据,
    mData.get(id).put("pic", bm);
    }
    else {//模拟从网络获取
    try {
    Thread.sleep(200);//模拟网络延时
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    mData.get(id).put("pic", BitmapFactory.decodeResource(getResources(), R.drawable.cool));
    }
    return null;
    }

    protected void onPostExecute (Void result) {
    mAdapter.notifyDataSetChanged();
    }

    }

    }

    //仿usertask

    改动了一下

    package com.example.myusertask;

    import java.util.concurrent.Callable;
    import java.util.concurrent.CancellationException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.ThreadFactory;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    import java.util.concurrent.atomic.AtomicInteger;

    import android.os.Handler;
    import android.os.Message;
    import android.os.Process;

    public abstract class PreReadTask<Params, Progress, Result> {
    private static final String LOG_TAG = "FifoAsyncTask";

    // private static final int CORE_POOL_SIZE = 5;
    // private static final int MAXIMUM_POOL_SIZE = 5;
    // private static final int KEEP_ALIVE = 1;

    // private static final BlockingQueue<Runnable> sWorkQueue =
    // new LinkedBlockingQueue<Runnable>();
    //
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
    private final AtomicInteger mCount = new AtomicInteger(1);

    public Thread newThread(Runnable r) {
    return new Thread(r, "PreReadTask #" + mCount.getAndIncrement());
    }
    };

    private static final ExecutorService sExecutor = Executors.newSingleThreadExecutor(sThreadFactory);//只有一个工作线程的线程池

    private static final int MESSAGE_POST_RESULT = 0x1;
    private static final int MESSAGE_POST_PROGRESS = 0x2;
    private static final int MESSAGE_POST_CANCEL = 0x3;

    private static final InternalHandler sHandler = new InternalHandler();

    private final WorkerRunnable<Params, Result> mWorker;
    private final FutureTask<Result> mFuture;

    private volatile Status mStatus = Status.PENDING;

    /**
    * Indicates the current status of the task. Each status will be set only once
    * during the lifetime of a task.
    */
    public enum Status {
    /**
    * Indicates that the task has not been executed yet.
    */
    PENDING,
    /**
    * Indicates that the task is running.
    */
    RUNNING,
    /**
    * Indicates that {@link FifoAsyncTask#onPostExecute} has finished.
    */
    FINISHED,
    }

    /**
    * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
    */
    public PreReadTask() {
    mWorker = new WorkerRunnable<Params, Result>() {
    public Result call() throws Exception {
    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    return doInBackground(mParams);
    }
    };

    mFuture = new FutureTask<Result>(mWorker) {
    @SuppressWarnings("unchecked")
    @Override
    protected void done() {
    Message message;
    Result result = null;

    try {
    result = get();
    } catch (InterruptedException e) {
    android.util.Log.w(LOG_TAG, e);
    } catch (ExecutionException e) {
    throw new RuntimeException("An error occured while executing doInBackground()",
    e.getCause());
    } catch (CancellationException e) {
    message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
    new PreReadTaskResult<Result>(PreReadTask.this, (Result[]) null));
    message.sendToTarget();
    return;
    } catch (Throwable t) {
    throw new RuntimeException("An error occured while executing "
    + "doInBackground()", t);
    }

    message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
    new PreReadTaskResult<Result>(PreReadTask.this, result));
    message.sendToTarget();
    }
    };
    }

    /**
    * Returns the current status of this task.
    *
    * @return The current status.
    */
    public final Status getStatus() {
    return mStatus;
    }

    /**
    * Override this method to perform a computation on a background thread. The
    * specified parameters are the parameters passed to {@link #execute}
    * by the caller of this task.
    *
    * This method can call {@link #publishProgress} to publish updates
    * on the UI thread.
    *
    * @param params The parameters of the task.
    *
    * @return A result, defined by the subclass of this task.
    *
    * @see #onPreExecute()
    * @see #onPostExecute
    * @see #publishProgress
    */
    protected abstract Result doInBackground(Params... params);

    /**
    * Runs on the UI thread before {@link #doInBackground}.
    *
    * @see #onPostExecute
    * @see #doInBackground
    */
    protected void onPreExecute() {
    }

    /**
    * Runs on the UI thread after {@link #doInBackground}. The
    * specified result is the value returned by {@link #doInBackground}
    * or null if the task was cancelled or an exception occured.
    *
    * @param result The result of the operation computed by {@link #doInBackground}.
    *
    * @see #onPreExecute
    * @see #doInBackground
    */
    @SuppressWarnings({"UnusedDeclaration"})
    protected void onPostExecute(Result result) {
    }

    /**
    * Runs on the UI thread after {@link #publishProgress} is invoked.
    * The specified values are the values passed to {@link #publishProgress}.
    *
    * @param values The values indicating progress.
    *
    * @see #publishProgress
    * @see #doInBackground
    */
    @SuppressWarnings({"UnusedDeclaration"})
    protected void onProgressUpdate(Progress... values) {
    }

    /**
    * Runs on the UI thread after {@link #cancel(boolean)} is invoked.
    *
    * @see #cancel(boolean)
    * @see #isCancelled()
    */
    protected void onCancelled() {
    }

    /**
    * Returns <tt>true</tt> if this task was cancelled before it completed
    * normally.
    *
    * @return <tt>true</tt> if task was cancelled before it completed
    *
    * @see #cancel(boolean)
    */
    public final boolean isCancelled() {
    return mFuture.isCancelled();
    }

    /**
    * Attempts to cancel execution of this task. This attempt will
    * fail if the task has already completed, already been cancelled,
    * or could not be cancelled for some other reason. If successful,
    * and this task has not started when <tt>cancel</tt> is called,
    * this task should never run. If the task has already started,
    * then the <tt>mayInterruptIfRunning</tt> parameter determines
    * whether the thread executing this task should be interrupted in
    * an attempt to stop the task.
    *
    * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
    * task should be interrupted; otherwise, in-progress tasks are allowed
    * to complete.
    *
    * @return <tt>false</tt> if the task could not be cancelled,
    * typically because it has already completed normally;
    * <tt>true</tt> otherwise
    *
    * @see #isCancelled()
    * @see #onCancelled()
    */
    public final boolean cancel(boolean mayInterruptIfRunning) {
    return mFuture.cancel(mayInterruptIfRunning);
    }

    /**
    * Waits if necessary for the computation to complete, and then
    * retrieves its result.
    *
    * @return The computed result.
    *
    * @throws CancellationException If the computation was cancelled.
    * @throws ExecutionException If the computation threw an exception.
    * @throws InterruptedException If the current thread was interrupted
    * while waiting.
    */
    public final Result get() throws InterruptedException, ExecutionException {
    return mFuture.get();
    }

    /**
    * Waits if necessary for at most the given time for the computation
    * to complete, and then retrieves its result.
    *
    * @param timeout Time to wait before cancelling the operation.
    * @param unit The time unit for the timeout.
    *
    * @return The computed result.
    *
    * @throws CancellationException If the computation was cancelled.
    * @throws ExecutionException If the computation threw an exception.
    * @throws InterruptedException If the current thread was interrupted
    * while waiting.
    * @throws TimeoutException If the wait timed out.
    */
    public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
    ExecutionException, TimeoutException {
    return mFuture.get(timeout, unit);
    }

    /**
    * Executes the task with the specified parameters. The task returns
    * itself (this) so that the caller can keep a reference to it.
    *
    * This method must be invoked on the UI thread.
    *
    * @param params The parameters of the task.
    *
    * @return This instance of AsyncTask.
    *
    * @throws IllegalStateException If {@link #getStatus()} returns either
    * {@link FifoAsyncTask.Status#RUNNING} or {@link FifoAsyncTask.Status#FINISHED}.
    */
    public final PreReadTask<Params, Progress, Result> execute(Params... params) {
    if (mStatus != Status.PENDING) {
    switch (mStatus) {
    case RUNNING:
    throw new IllegalStateException("Cannot execute task:"
    + " the task is already running.");
    case FINISHED:
    throw new IllegalStateException("Cannot execute task:"
    + " the task has already been executed "
    + "(a task can be executed only once)");
    }
    }

    mStatus = Status.RUNNING;

    onPreExecute();

    mWorker.mParams = params;
    sExecutor.execute(mFuture);

    return this;
    }

    /**
    * This method can be invoked from {@link #doInBackground} to
    * publish updates on the UI thread while the background computation is
    * still running. Each call to this method will trigger the execution of
    * {@link #onProgressUpdate} on the UI thread.
    *
    * @param values The progress values to update the UI with.
    *
    * @see #onProgressUpdate
    * @see #doInBackground
    */
    protected final void publishProgress(Progress... values) {
    sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
    new PreReadTaskResult<Progress>(this, values)).sendToTarget();
    }

    private void finish(Result result) {
    if (isCancelled()) result = null;
    onPostExecute(result);
    mStatus = Status.FINISHED;
    }

    private static class InternalHandler extends Handler {
    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    public void handleMessage(Message msg) {
    PreReadTaskResult result = (PreReadTaskResult) msg.obj;
    switch (msg.what) {
    case MESSAGE_POST_RESULT:
    // There is only one result
    result.mTask.finish(result.mData[0]);
    break;
    case MESSAGE_POST_PROGRESS:
    result.mTask.onProgressUpdate(result.mData);
    break;
    case MESSAGE_POST_CANCEL:
    result.mTask.onCancelled();
    break;
    }
    }
    }

    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
    Params[] mParams;
    }

    @SuppressWarnings({"RawUseOfParameterizedType"})
    private static class PreReadTaskResult<Data> {
    final PreReadTask mTask;
    final Data[] mData;

    PreReadTaskResult(PreReadTask task, Data... data) {
    mTask = task;
    mData = data;
    }
    }
    }

    工具类

    package com.example.myusertask;

    import java.util.AbstractMap;
    import java.util.concurrent.ConcurrentHashMap;

    public class Data {
    private static AbstractMap<String, Object> mData = new ConcurrentHashMap<String, Object>();

    private Data() {

    }

    public static void putData(String key,Object obj) {
    mData.put(key, obj);
    }

    public static Object getData(String key) {
    return mData.get(key);
    }
    }

    ========

    布局就不展示了,listview  +  要显示的子页面

    当然 出现了内存溢出,思路可能是判断移除,这不重要 主要是展示预加载做法,ok挺尸。。。

  • 相关阅读:
    Gym 101194L / UVALive 7908
    POJ 2259
    POJ 2559
    Gym 101194E / UVALive 7901
    Gym 101194D / UVALive 7900
    一种整数集上二分的正确写法
    日常训练记录
    Gym 101194C / UVALive 7899
    Gym 101194A / UVALive 7897
    HDU 5542
  • 原文地址:https://www.cnblogs.com/yizuochengchi2012/p/4996455.html
Copyright © 2011-2022 走看看