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 {

@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> 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>();

mAdapter = new CustomAdapter();

mListView.setAdapter(mAdapter);

for(int i = 0; i < 100; i++) {//初始化100项数据

HashMap data = new HashMap();

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 {

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 {

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 sWorkQueue =

// new LinkedBlockingQueue();

//

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 mWorker;

private final FutureTask 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() {

public Result call() throws Exception {

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

return doInBackground(mParams);

}

};

mFuture = new FutureTask(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(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(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 true if this task was cancelled before it completed

* normally.

*

* @return true 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 cancel is called,

* this task should never run. If the task has already started,

* then the mayInterruptIfRunning parameter determines

* whether the thread executing this task should be interrupted in

* an attempt to stop the task.

*

* @param mayInterruptIfRunning true if the thread executing this

* task should be interrupted; otherwise, in-progress tasks are allowed

* to complete.

*

* @return false if the task could not be cancelled,

* typically because it has already completed normally;

* true 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 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(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 implements Callable {

Params[] mParams;

}

@SuppressWarnings({"RawUseOfParameterizedType"})

private static class PreReadTaskResult {

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 mData = new ConcurrentHashMap();

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挺尸。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值