我對這個錯誤感到困惑 -只有原來的線程錯誤
只有創建視圖層次可以觸摸其觀點原來的線程。
我有一個類,它在UI中的runnable/thread塊內調用。沒有企圖 - 據我所知,??? - 由操縱內可運行的UI,或者它調用,如下面的類.....
public class MonthSort {
Handler handler;
int imageWidth;
List<PhotoData> photoList;
public MonthSort(Handler handler2, int width, List<PhotoData> pList) {
photoList = new ArrayList<PhotoData>();
photoList = pList;
imageWidth = width;
handler = handler2;
}
public void sortFiles()
{
int month, photoCount;
File fileName = new File("");
Message msg = handler.obtainMessage();
for (int i = 0; i < 12; i++) {
month = i + 1;
photoCount = 0;
for (PhotoData pd : photoList) {
if(month == pd.month)
{
if(photoCount == 0)
fileName = pd.fileName;
photoCount++;
}
}
if(photoCount != 0)
{
Bundle bundle = new Bundle();
bundle.putString("filename", fileName.toString());
bundle.putInt("month", month);
bundle.putInt("count", photoCount);
byte[] thumbNail = getThumbnail(fileName, imageWidth);
bundle.putByteArray("thumbnail", thumbNail);
msg.setData(bundle);
handler.dispatchMessage(msg);
}
}
Bundle bundle = new Bundle();
bundle.putBoolean("end", true);
msg.setData(bundle);
handler.dispatchMessage(msg);
}
private byte[] getThumbnail(File file, int size)
{
/** The object of this code is to reduce the bitmap for thumbnail display,
* Not just to reduce dimensions, but to reduce the physical size of the
* bitmap ready, so that several bitmaps can remain in memory without
* an outOfMemoryException error.*/
byte[] thumbnail;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(
file.toString(), options);
options.inSampleSize = calculateInSampleSize(
options, imageWidth, imageWidth);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(file.toString(),
options);
/*now the size of the Bitmap is manageable, we set about sizing the
* thumbnail correctly, preserving the Aspect Ratio */
final int REQUIRED_SIZE = imageWidth;
int thumbHeight = REQUIRED_SIZE, thumbWidth = REQUIRED_SIZE;
float ratio = (float) bitmap.getWidth() // Work out the aspect ratio.
/(float) bitmap.getHeight();
if (ratio == 1) {
thumbHeight = REQUIRED_SIZE;
thumbWidth = REQUIRED_SIZE;
} else if (ratio < 1) {
thumbHeight = REQUIRED_SIZE;
thumbWidth = (int) ((float) REQUIRED_SIZE * (float) ratio);
} else {
thumbWidth = REQUIRED_SIZE;
thumbHeight = (int) ((float) REQUIRED_SIZE/(float) ratio);
}
Bitmap bitmap2 = Bitmap.createScaledBitmap(
bitmap, thumbWidth, thumbHeight, false);
ByteArrayOutputStream out;
try {
out = new ByteArrayOutputStream();
bitmap2.compress(CompressFormat.JPEG, 30, out); // Compress the bitmap
thumbnail = out.toByteArray();
out.close(); // close the out stream.
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
thumbnail = new byte[1];
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
thumbnail = new byte[1];
}
return thumbnail;
}
private int calculateInSampleSize(Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if(height > reqHeight || width > reqWidth)
{
final int heightRatio = Math.round((float) height/(float) reqHeight);
final int widthRatio = Math.round((float) width/(float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
主線程在頂部的處理程序(請參見下面的代碼 - 只是爲了處理程序代碼簡潔)爲正常,並使用自定義的轉接器(包括代碼)的notifyDataSetChanged()方法...
public class MonthActivity extends Activity {
List<PhotoData> photoList;
static List<MonthData> photos;
int imageWidth;
GridView photoGrid;
static ImageAdapter2 iAdapter2;
static int year;
Thread monthSortThread;
static Handler handler2 = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
Bundle bundle = msg.getData(); // Get the message sent to the Handler.
boolean ended = bundle.getBoolean("end");
if(ended)
{
iAdapter2.notifyDataSetChanged();
//Toast.makeText(getBaseContext(), "FINISHED !!!", Toast.LENGTH_LONG).show();
} else
{
MonthData md = new MonthData();
md.monthValue = bundle.getInt("month");
md.monthString = getMonthString(md.monthValue);
Log.d("Debug", md.monthString + " " + String.valueOf(year));
md.count = bundle.getInt("count");
byte[] tn = bundle.getByteArray("thumbnail");
md.thumbnail = BitmapFactory.decodeByteArray(tn, 0, tn.length);
photos.add(md);
iAdapter2.notifyDataSetChanged();
}
}
};
(適配器代碼)
public class ImageAdapter2 extends BaseAdapter{
List<MonthData> photos;
Context context;
int year, imageWidth;
public ImageAdapter2 (Context ct, List<MonthData> pList, int yr, int i) {
photos = new ArrayList<MonthData>();
photos = pList;
context = ct;
year = yr;
imageWidth = i;
}
@Override
public int getCount() {
return photos.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View myView = null;
if(convertView == null)
{
LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
myView = li.inflate(R.layout.grid_cell, null);
} else
{
myView = convertView;
}
TextView tv = (TextView)myView.findViewById(R.id.photoText);
if(year == 0)
{
int count = photos.get(position).count;
tv.setText(String.valueOf(count));
} else
{
int count = photos.get(position).count;
String month = photos.get(position).monthString;
String yearString = String.valueOf(year);
tv.setText(month + " " + yearString + " (" + String.valueOf(count) + ")");
}
ImageView iv = (ImageView)myView.findViewById(R.id.photoViewGridCell);
iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
iv.setPadding(0, 0, 0, 0);
iv.setLayoutParams(new LinearLayout.LayoutParams(imageWidth, imageWidth));
iv.setMaxHeight(imageWidth);
iv.setMaxWidth(imageWidth);
iv.setImageBitmap(photos.get(position).thumbnail);
return myView;
}
}
請注意,在選擇自定義視圖(特別是視圖集合,在單獨的xml佈局文件中)時,通過一個意圖調用MonthActivity ImageAdapter2只是用於「開始」活動的類似適配器上的一個小變體,自定義視圖略有不同。此外,ImageAdapter2已正確「連接」到所需的佈局,並且在onCreate()方法中啓動,它甚至可以成功運行構造函數,但儘管適配器的getView方法中有幾個不同的斷點,但它們都不會到達調試時......非常令人沮喪..有什麼想法?
您可能試圖從另一個線程訪問視圖..... – Triode
也發佈堆棧跟蹤。 – Sam