Reputation: 3910
I have some network requests in my app, and whenever the network related code is called, I got this exception. I already put them in background:
@Background
protected void getBitmapFromURL(String src, ImageView img) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
updateImageView(BitmapFactory.decodeStream(input), img);
return;
} catch (IOException e) {
System.out.println("************** network exception: download image failed");
return;
}
}
@UiThread
protected void updateImageView(Bitmap bitmap, ImageView img) {
img.setImageBitmap(bitmap);
return;
}
But the error still exists. I'm implementing my own adapter here, which extends BaseAdapter. I annotated it with @EBean
and declared with @Bean
in my activity file. The constructor only takes Context
parameter, I put the initialization of other parameters in a separate method.
So I think the setup satisfies the requirements of androidannotation, and if the network operations are done in the background, why should this error occur?
The class I'm extending:
@EBean
public class MomentViewAdapter extends BaseAdapter {
protected LayoutInflater mInflater;
protected Context mContext;
protected List<FavoriteInfo> mDatas;
protected int mItemLayoutId;
public MomentViewAdapter(Context context) {
this.mContext = context;
// this.mInflater = LayoutInflater.from(mContext);
// this.mDatas = mDatas;
// this.mItemLayoutId = itemLayoutId;
}
public void setUp(List<FavoriteInfo> mDatas, int itemLayoutId) {
this.mInflater = LayoutInflater.from(mContext);
this.mDatas = mDatas;
this.mItemLayoutId = itemLayoutId;
}
@Override
public int getCount()
{
return mDatas.size();
}
@Override
public FavoriteInfo getItem(int position)
{
return mDatas.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(mItemLayoutId, parent, false);
}
ImageView img = (ImageView) convertView.findViewById(R.id.detail_moment_camera_picture);
if (mDatas.get(position).isVideoFavorite()) {
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(mDatas.get(position).getVideoURL(), MediaStore.Video.Thumbnails.MINI_KIND);
img.setImageBitmap(bitmap);
} else {
getBitmapFromURL(mDatas.get(position).getImageURL(), img);
// img.setImageBitmap(getBitmapFromURL(mDatas.get(position).getImageURL()));
}
img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, GeneratedClassUtils.get(MomentDetailActivity.class));
Bundle mBundle = new Bundle();
mBundle.putSerializable(FavoriteInfo.KEY, mDatas.get(position));
mBundle.putBoolean(CollectionInfo.KEY_WATCH_FLAG, false);
intent.putExtras(mBundle);
mContext.startActivity(intent);
}
});
return convertView;
}
StackTrace (error is in MomentViewAdapter):
09-02 11:35:17.302 30956-30956/com.bloomsky.bloomsky E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.bloomsky.bloomsky, PID: 30956
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:249)
at libcore.io.IoBridge.recvfrom(IoBridge.java:553)
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:485)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at com.android.okio.Okio$2.read(Okio.java:113)
at com.android.okio.RealBufferedSource.indexOf(RealBufferedSource.java:147)
at com.android.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:94)
at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:175)
at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:101)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:616)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:379)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:323)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:190)
at com.bloomsky.android.ui.adapter.MomentViewAdapter.getBitmapFromURL(MomentViewAdapter.java:132)
at com.bloomsky.android.ui.adapter.MomentViewAdapter.getView(MomentViewAdapter.java:85)
at android.widget.AbsListView.obtainView(AbsListView.java:2346)
at android.widget.GridView.makeAndAddView(GridView.java:1433)
at android.widget.GridView.makeRow(GridView.java:361)
at android.widget.GridView.fillDown(GridView.java:302)
at android.widget.GridView.fillFromTop(GridView.java:437)
at android.widget.GridView.layoutChildren(GridView.java:1276)
at android.widget.AbsListView.onLayout(AbsListView.java:2150)
at android.view.View.layout(View.java:15604)
at android.view.ViewGroup.layout(ViewGroup.java:4967)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15604)
at android.view.ViewGroup.layout(ViewGroup.java:4967)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.widget.ScrollView.onLayout(ScrollView.java:1502)
at android.view.View.layout(View.java:15604)
at android.view.ViewGroup.layout(ViewGroup.java:4967)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.view.View.layout(View.java:15604)
at android.view.ViewGroup.layout(ViewGroup.java:4967)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15604)
at android.view.ViewGroup.layout(ViewGroup.java:4967)
at in.srain.cube.views.ptr.PtrFrameLayout.layoutChildren(PtrFrameLayout.java:247)
at in.srain.cube.views.ptr.PtrFrameLayout.onLayout(PtrFrameLayout.java:216)
at android.view.View.layout(View.java:15604)
at android.view.ViewGroup.layout(ViewGroup.java:4967)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077)
at android.view.View.layout(View.java:15604)
at android.view.ViewGroup.layout(ViewGroup.java:4967)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at com.bloomsky.android.ui.SwipeBackLayout.onLayout(SwipeBackLayout.java:233)
at android.view.View.layout(View.java:15604)
at android.view.ViewGroup.layout(ViewGroup.java:4967)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.view.View.layout(View.java:15604
And as requested, here is the related activity code:
@Bean
MomentViewAdapter mGridViewAdapter;mGridViewAdapter = new MomentViewAdapter(this);
mGridViewAdapter.setUp(mMomentDatas, R.layout.device_detail_moment_listitem_simple);
mGridView.setAdapter(mGridViewAdapter);
Upvotes: 4
Views: 364
Reputation: 12207
The problem here is you are not using the generated class, but your annotated one which of course does not contain any enhancements. You have to create or inject your enhanced adapter to the class where you want to use it, then call the background method on that instance.
@EActivity
public class YourActivity {
@Bean // will inject instance of generated MomentViewAdapter_
MomentViewAdapter adapter;
@AfterInject // injected beans are only available from here
public void afterInject() {
yourList.setAdapter(adapter);
}
}
Upvotes: 2
Reputation: 22212
Try to do it this way
ImageView imageView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView = (ImageView) findViewById(R.id.imageView);
// Create an object for subclass of AsyncTask
BitmapDownloaderTask task = new BitmapDownloaderTask();
.
.
.
}
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
.
.
.
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
return getBitmapFromURL(params...);
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
protected void getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
//New Line added
final Bitmap bitmap = BitmapFactory.decodeStream(input);
//return bitmap
return bitmap;
} catch (IOException e) {
System.out.println("************** network exception: download image failed");
return;
}
}
But instead of doing in this way I would recommend you the use of Volley.
Upvotes: 2