将图像从URL获取到ImageView中

时间:2013-02-25 22:09:01

标签: android xml-parsing android-asynctask android-imageview

我正在继续努力为学校报纸制作应用程序。我最新的挑战是让每个俱乐部和组织徽标出现在活动中的ImageView中,并显示有关俱乐部的其他详细信息。

出于显而易见的原因,我不想在应用程序中存储所有这些图像,我宁愿从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("");
}

}

3 个答案:

答案 0 :(得分: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);  
      }

}

并从Activity:

执行AsyncTask
String str_url=intent.getStringExtra("keyLogo");
GetImageFromServer asyObj=new GetImageFromServer(str_url,Your_Activity.this);
asyObj.execute("");

答案 1 :(得分:3)

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

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

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

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

答案 2 :(得分:0)

是的,你肯定想在一个单独的线程上通过网络抓取图像。您可以设置doInBackground来获取图像,然后在onpostexecute中将位图设置为imageview。