0

我正在继续努力为我的校报制作应用程序。我最新的挑战是让每个俱乐部和组织的标志出现在一个 ImageView 中,该 ImageView 与俱乐部的其他详细信息一起出现在 Activity 中。

出于显而易见的原因,我不想在应用程序中存储所有这些图像,我宁愿从 URL 中获取它们。我认为这样做的一种方法是以下代码段:

Intent intent = getIntent();
 Bitmap bm = null;
try {
    bm = BitmapFactory.decodeStream((InputStream)new URL(intent.getStringExtra("keyLogo")).getContent());
} catch (MalformedURLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
 detailsLogo.setImageBitmap(bm);

我从我创建的 XML 文件中获取一个 URL,该文件包含校园内的所有俱乐部及其信息。这样,当我想在应用程序中更改某些内容时,我只需要更改 XML。

这里的问题是它抛出了 NetworkOnMainThread 异常。这可以放入我的活动中的 AsyncTask 并以这种方式运行吗?任何意见,将不胜感激。

编辑:链接的问题不能满足我的需求。其中一个答案很接近,但我的问题特别需要一个异步任务,该问题接受的答案不包括在内。

这是使用接受的答案和其他部分完成的活动:

public class OrgDetails extends Activity {

/*******************************************************************
 * Async Task
 ******************************************************************/
private class GetImageFromServer extends AsyncTask<String, Void, Bitmap> {

    String url;
    Context context;
    private Bitmap image;
    ImageView detailsLogo = (ImageView)findViewById(R.id.detailsLogo);

    public GetImageFromServer(String url, Context context){
        this.url = url;
        this.context = context;
    }

    @Override
    protected Bitmap doInBackground(String... params){
        try{
            URL urli = new URL(this.url);
            URLConnection ucon = urli.openConnection();
            image = BitmapFactory.decodeStream(ucon.getInputStream());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;  //<<< return Bitmap
    }
    @Override
    protected void onPostExecute(Bitmap result){ 
        detailsLogo.setImageBitmap(result);
    }

}
/*******************************************************************
 * End Async Task
 ******************************************************************/

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.orgdetails);

     TextView detailsSname = (TextView)findViewById(R.id.detailsSname);
     TextView detailsLname = (TextView)findViewById(R.id.detailsLname);
     TextView detailsDescription = (TextView)findViewById(R.id.detailsDescription);

     Intent intent = getIntent();

     detailsLname.setText(intent.getStringExtra("keyLname"));
     detailsSname.setText(intent.getStringExtra("keySname"));
     detailsDescription.setText(intent.getStringExtra("keyDescription"));

     String str_url = intent.getStringExtra("keyLogo");
     GetImageFromServer asyObj = new GetImageFromServer(str_url,OrgDetails.this);
     asyObj.execute("");
}

}
4

3 回答 3

3

使用 AsyncTask 更改代码以从服务器获取图像,而不是在主 UI 线程上执行网络操作。通过将 AsyncTask 扩展为 Activity 的内部类:

private class GetImageFromServer extends AsyncTask<String, Void, Bitmap> {

     String url;
     Context context;
     public GetImageFromServer(URL url,Context context){
       this.url=url;
       this.context=context;
        }
      @Override
      protected Bitmap doInBackground(String... params) {
        bm = BitmapFactory.decodeStream((InputStream)new URL(url).getContent());
        return bm;  //<<< return Bitmap
      }      

      @Override
      protected void onPostExecute(Bitmap result) { 
            detailsLogo.setImageBitmap(result);  
      }

}

AsyncTask从 Activity 执行:

String str_url=intent.getStringExtra("keyLogo");
GetImageFromServer asyObj=new GetImageFromServer(str_url,Your_Activity.this);
asyObj.execute("");
于 2013-02-25T22:23:36.787 回答
3

当您尝试在 UI 线程中执行网络操作时,您会收到 NetworkOnMainThread 异常。

您应该按照您的建议将其放入 AsyncTask 中,并且您的下载代码应该检索 InputStream 而不是像这样转换内容:

URL url = new URL(path);
URLConnection ucon = url.openConnection();
Bitmap image = BitmapFactory.decodeStream(ucon.getInputStream());

如果您还想更灵活地控制您的图像,请考虑为您的位图对象使用图像适配器。这些是扩展 BaseAdapter 的容器,可以为您提供额外的控件来操作图像,例如缩放。

于 2013-02-25T22:40:03.057 回答
0

是的,您肯定希望在单独的线程上通过网络抓取图像。您可以设置 doInBackground 以获取图像,然后在 onpostexecute 中将位图设置为图像视图。

于 2013-02-25T22:23:48.770 回答