我正在继续努力为学校报纸制作应用程序。我最新的挑战是让每个俱乐部和组织徽标出现在活动中的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("");
}
}
答案 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。