2013-04-12 18 views
0

我對這個錯誤感到困惑 -只有原來的線程錯誤

只有創建視圖層次可以觸摸其觀點原來的線程。

我有一個類,它在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方法中有幾個不同的斷點,但它們都不會到達調試時......非常令人沮喪..有什麼想法?

+0

您可能試圖從另一個線程訪問視圖..... – Triode

+0

也發佈堆棧跟蹤。 – Sam

回答

1

當您調用Runnable時,將Runnable放入runOnUiThread方法中。

+0

謝謝。這是整理它! –