2015-09-02 4 views
4

У меня есть сетевые запросы в моем приложении, и всякий раз, когда вызывается сетевой код, я получил это исключение. Я уже положил их в фоновом режиме:Android NetworkOnMainThreadException в фоновых методах

@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; 
    } 

Но ошибка все еще существует. Я реализую свой собственный адаптер здесь, который расширяет BaseAdapter. Я аннотировал его @EBean и объявлял @Bean в своем файле активности. Конструктор принимает только параметр Context, я поместил инициализацию других параметров в отдельный метод.

Итак, я думаю, что настройка удовлетворяет требованиям androidannotation, и если сетевые операции выполняются в фоновом режиме, почему эта ошибка возникает?

Класс Я простирающийся:

@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 (ошибка в 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 

И в соответствии с просьбой, здесь соответствующий код вида деятельности:

 @Bean 
     MomentViewAdapter mGridViewAdapter;mGridViewAdapter = new MomentViewAdapter(this); 
     mGridViewAdapter.setUp(mMomentDatas, R.layout.device_detail_moment_listitem_simple); 
     mGridView.setAdapter(mGridViewAdapter); 
+0

Просьба отправить трассировку стека и показать, где вы вызываете 'getBitmapFromURL()'. Вы также можете использовать одно из, казалось бы, бесконечное количество [загрузочных библиотек для Android] (https://android-arsenal.com/tag/46), поскольку они уже решили эту проблему. – CommonsWare

+0

Вы используете это в классе Async? –

+0

@MarkGilchrist я так и считаю. Необходимо было позаботиться об андроидах. –

ответ

2

Проблема в том, что вы не используете сгенерированный класс, но ваш аннотированный, который, конечно же, не содержит никаких улучшений. Вам необходимо создать или добавить расширенный адаптер в класс, в котором вы хотите его использовать, а затем вызвать фоновый метод для этого экземпляра.

@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); 
    } 
} 
+0

Я получил: вызвано: java.lang.NullPointerException: попытка вызвать виртуальный метод void android.widget.GridView.setAdapter (android.widget.ListAdapter) 'на нулевой ссылке объекта на com.bloomsky.android.activities. common.DeviceDetailActivity.afterInject (DeviceDetailActivity.java:626) –

+0

, поэтому он говорит, что «адаптер» имеет значение null. Но я использовал: @AfterInject // введенные bean-компоненты доступны только здесь public void afterInject() { mGridViewAdapter.setUp (mMomentDatas, R.layout.device_detail_moment_listitem_simple); mGridView.setAdapter (mGridViewAdapter); } и аннотировали его с помощью \ @Bean –

+0

На самом деле я использовал EBean в течение некоторого времени, но я никогда не использовал аннотацию AfterInject. Все мои предыдущие коды безупречно работают без него. Я думал, что экземпляр автоматически создается после использования @Bean –

2

Постарайтесь сделать это таким образом

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; 
     } 
    } 

Но вместо этого я рекомендовал бы использовать Volley.

+1

Вступление Волей выглядит очень мощным. Я собираюсь изучить документы и попробовать. Итак, вы думаете, что здесь не работает корректная работа? –

+0

И откуда происходит образы imageViewReference? –

+0

@JFreebird Я отредактировал свой ответ. Это был код старого проекта, который у меня был, поэтому я удалил код –