gpt4 book ai didi

android - 延迟加载列表 - 这里需要一点帮助

转载 作者:行者123 更新时间:2023-11-29 22:21:37 35 4
gpt4 key购买 nike

所以基本上每个人在某一时刻都需要这样做,从网络或缓存中加载一些图像到 ListView 。我找到了 Fedor 的 Lazy List 的一个非常好的例子,我试图让它做我需要的,但我有一些问题。我的情况下的图像是加密的。所以我需要在设备上加密它们并在 ListView 中显示它们。现在我得到了这个代码:

private Bitmap getBitmap(String src) {
Bitmap myBitmap = null;
try {

//Decryption
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec("01234567890abcde".getBytes(), "AES");
IvParameterSpec ivSpec = new IvParameterSpec("fedcba9876543210".getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

AssetManager is = this.getAssets();
InputStream input = is.open(src); //open file in asset manager
CipherInputStream cis = new CipherInputStream(input, cipher);

myBitmap = BitmapFactory.decodeStream(cis);

}
catch(Exception e){
e.printStackTrace();
Log.v("ERROR","Error : "+e);
}


return myBitmap;


} catch (IOException e) {
e.printStackTrace();
Log.v("ERROR","Error : "+e);

return null;
}
}

据我所知,这是不正确的(我不明白为什么,这就是我需要帮助的原因)。这是我得到的异常:

08-11 13:38:51.163: WARN/System.err(4731): java.lang.NullPointerException
08-11 13:38:51.163: WARN/System.err(4731): at android.content.ContextWrapper.getAssets(ContextWrapper.java:74)
08-11 13:38:51.163: WARN/System.err(4731): at com.custom.lazylist.ImageLoader.getBitmap(ImageLoader.java:79)
08-11 13:38:51.163: WARN/System.err(4731): at com.custom.lazylist.ImageLoader.access$0(ImageLoader.java:70)
08-11 13:38:51.163: WARN/System.err(4731): at com.custom.lazylist.ImageLoader$PhotosLoader.run(ImageLoader.java:200)

这是 ImageLoader 类的全部代码:

package com.custom.lazylist;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Stack;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.fedorvlasov.lazylist.R;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.ImageView;

public class ImageLoader extends Activity {

//the simplest in-memory cache implementation. This should be replaced with something like SoftReference or BitmapOptions.inPurgeable(since 1.6)
private HashMap<String, Bitmap> cache=new HashMap<String, Bitmap>();

private File cacheDir;

public ImageLoader(Context context){
//Make the background thead low priority. This way it will not affect the UI performance
photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);

//Find the dir to save cached images
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
else
cacheDir=context.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
}

final int stub_id=R.drawable.stub;
public void DisplayImage(String url, Activity activity, ImageView imageView)
{
if(cache.containsKey(url))
imageView.setImageBitmap(cache.get(url));
else
{
queuePhoto(url, activity, imageView);
imageView.setImageResource(stub_id);
}
}

private void queuePhoto(String url, Activity activity, ImageView imageView)
{
//This ImageView may be used for other images before. So there may be some old tasks in the queue. We need to discard them.
photosQueue.Clean(imageView);
PhotoToLoad p=new PhotoToLoad(url, imageView);
synchronized(photosQueue.photosToLoad){
photosQueue.photosToLoad.push(p);
photosQueue.photosToLoad.notifyAll();
}

//start thread if it's not started yet
if(photoLoaderThread.getState()==Thread.State.NEW)
photoLoaderThread.start();
}

private Bitmap getBitmap(String src) {
Bitmap myBitmap = null;
//Decryption
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec("01234567890abcde".getBytes(), "AES");
IvParameterSpec ivSpec = new IvParameterSpec("fedcba9876543210".getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

AssetManager is = this.getAssets();
InputStream input = is.open(src); //open file in asset manager
CipherInputStream cis = new CipherInputStream(input, cipher);

myBitmap = BitmapFactory.decodeStream(cis);

}
catch(Exception e){
e.printStackTrace();
Log.v("ERROR","Error : "+e);
}


return myBitmap;
}

//Task for the queue
private class PhotoToLoad
{
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i){
url=u;
imageView=i;
}
}

PhotosQueue photosQueue=new PhotosQueue();

public void stopThread()
{
photoLoaderThread.interrupt();
}

//stores list of photos to download
class PhotosQueue
{
private Stack<PhotoToLoad> photosToLoad=new Stack<PhotoToLoad>();

//removes all instances of this ImageView
public void Clean(ImageView image)
{
for(int j=0 ;j<photosToLoad.size();){
if(photosToLoad.get(j).imageView==image)
photosToLoad.remove(j);
else
++j;
}
}
}

class PhotosLoader extends Thread {
public void run() {
try {
while(true)
{
//thread waits until there are any images to load in the queue
if(photosQueue.photosToLoad.size()==0)
synchronized(photosQueue.photosToLoad){
photosQueue.photosToLoad.wait();
}
if(photosQueue.photosToLoad.size()!=0)
{
PhotoToLoad photoToLoad;
synchronized(photosQueue.photosToLoad){
photoToLoad=photosQueue.photosToLoad.pop();
}
Bitmap bmp=getBitmap(photoToLoad.url);
cache.put(photoToLoad.url, bmp);
Object tag=photoToLoad.imageView.getTag();
if(tag!=null && ((String)tag).equals(photoToLoad.url)){
BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView);
Activity a=(Activity)photoToLoad.imageView.getContext();
a.runOnUiThread(bd);
}
}
if(Thread.interrupted())
break;
}
} catch (InterruptedException e) {
//allow thread to exit
}
}
}

PhotosLoader photoLoaderThread=new PhotosLoader();

//Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable
{
Bitmap bitmap;
ImageView imageView;
public BitmapDisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;}
public void run()
{
if(bitmap!=null)
imageView.setImageBitmap(bitmap);
else
imageView.setImageResource(stub_id);
}
}

public void clearCache() {
//clear memory cache
cache.clear();

//clear SD cache
File[] files=cacheDir.listFiles();
for(File f:files)
f.delete();
}



}

希望有人能帮我解决这个问题,因为我真的很想了解如何使用延迟加载列表。

P.S. 实际上我意识到我正在扩展 Activity 而没有重写 onCreate,但这是唯一的方法:AssetManager is = is.getAssets(); .否则,如果我删除扩展,我不会显示错误:The method getAssets() is undefined for the type ImageLoader

最佳答案

有两处错误:

  1. 如果 ImageLoader 不是 Activity,那么您不应该扩展 Activity(正如您所承认的)。每次您发现自己需要在不应成为 Activity 的对象中扩展 Activity 时,您都需要一个Context。通常将上下文保存为成员变量 private Context mContext; 就足够了,然后将遇到问题的行更改为 AssetManager is = this.mContext.getAssets()
  2. 这对您来说行不通。您需要使用 AsyncTask 或将您的 ImageLoader 变成服务。问题是您需要后台线程中的上下文。但是,如果创建 ImageLoader(以及后台线程)的 Activity 消失了,当您的后台线程调用 getAssetManager() 时,mContext 可能不是有效的上下文。如果您将其变成一项服务,那么您的服务将是一个有效的上下文,并为您提供访问 Assets 管理器的权限。

创建服务的具体步骤超出了本答案的范围,但您可以从有关服务的 Android 文档开始:http://developer.android.com/guide/topics/fundamentals/services.html

编辑:备份评论的代码(下方)

...

// ***** ADDITION *****
private AssetManager mAssetManager;

public ImageLoader(Context context){
//Make the background thead low priority. This way it will not affect the UI performance
photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);
// ***** ADDITION *****
mAssetManager = context.getAssets();

//Find the dir to save cached images
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
else
cacheDir=context.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
}

private Bitmap getBitmap(String src) {
Bitmap myBitmap = null;
//Decryption
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec("01234567890abcde".getBytes(), "AES");
IvParameterSpec ivSpec = new IvParameterSpec("fedcba9876543210".getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

// ***** CHANGE *****
InputStream input = mAssetManager.open(src); //open file in asset manager
CipherInputStream cis = new CipherInputStream(input, cipher);

myBitmap = BitmapFactory.decodeStream(cis);

}
catch(Exception e){
e.printStackTrace();
Log.v("ERROR","Error : "+e);
}


return myBitmap;
}
....

关于android - 延迟加载列表 - 这里需要一点帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7026896/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com