2014-09-23 40 views
0

我创建了一个位图数组,并且正在更新listview中imageview中的数组元素。但它在主线程异常上显示网络。将位图数组设置为imageview时发生主线程异常的网络

下面是代码:

public class InTheaters extends Activity { 
    // the Rotten Tomatoes API key of your application! get this from their 
    // website 
    private static final String API_KEY = "xxxxxxxxxxxxxxxxxx"; 
    protected AdView adView; 
    // the number of movies you want to get in a single request to their web 
    // server 
    private static final int MOVIE_PAGE_LIMIT = 30; 
    private ListView moviesList; 
    String[] movieID; 
    MyAdapter ma; 
    ArrayList<String> movieTitles, releaseyear, castnames, rtscore, audscore; 
    ArrayList<Bitmap> posterbitmap; 
    Boolean fav = false; 
    ProgressBar progress; 
    TextView pleasewaittext; 
    Button retry; 
    JSONArray movies; 
    Bitmap mIcon_val; 

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

     movieTitles = new ArrayList<String>(); 
     releaseyear = new ArrayList<String>(); 
     castnames = new ArrayList<String>(); 
     rtscore = new ArrayList<String>(); 
     audscore = new ArrayList<String>(); 
     progress = (ProgressBar) findViewById(R.id.progress); 
     pleasewaittext = (TextView) findViewById(R.id.pleasewaittext); 
     retry = (Button) findViewById(R.id.retry); 

     ma = new MyAdapter(); 

     if(isNetworkAvailable()) 
     { 
     new RequestTask() 
       .execute("http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json?apikey=" 
         + API_KEY + "&page_limit=" + MOVIE_PAGE_LIMIT); 
     } 
     else 
     { 
      progress.setVisibility(View.GONE); 
      pleasewaittext.setText("No Internet Connectivity. Please check."); 
      retry.setVisibility(View.VISIBLE); 
     } 

     retry.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO Auto-generated method stub 
       if(isNetworkAvailable()) 
       { 
        progress.setVisibility(View.VISIBLE); 
        pleasewaittext.setVisibility(View.VISIBLE); 
        pleasewaittext.setText("Please wait.."); 
        retry.setVisibility(View.GONE); 
       new RequestTask() 
         .execute("http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json?apikey=" 
           + API_KEY + "&page_limit=" + MOVIE_PAGE_LIMIT); 
       } 
       else 
       { 
        progress.setVisibility(View.GONE); 
        pleasewaittext.setText("No Internet Connectivity. Please check."); 
        retry.setVisibility(View.VISIBLE); 
       } 
      } 
     }); 

     moviesList = (ListView) findViewById(R.id.list_movies); 
     moviesList 
       .setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() { 

        @Override 
        public void onItemClick(AdapterView<?> parent, View view, 
          int position, long id) { 
         // TODO Auto-generated method stub 
         String item = (String) moviesList 
           .getItemAtPosition(position); 
         String movieid = movieID[position]; 
         Intent intent = new Intent(InTheaters.this, 
           MovieInfo.class); 
         intent.putExtra("MovieID", movieid); 
         startActivity(intent); 
        } 
       }); 
    } 

    private void refreshMoviesName() { 
     moviesList.setAdapter(ma); 
     ma.notifyDataSetChanged(); 
     progress.setVisibility(View.GONE); 
     pleasewaittext.setVisibility(View.GONE); 
     retry.setVisibility(View.GONE); 
    } 

    public boolean isNetworkAvailable() { 
     ConnectivityManager connectivity = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
     if (connectivity == null) { 
      return false; 
     } else { 
      NetworkInfo[] info = connectivity.getAllNetworkInfo(); 
      if (info != null) { 
       for (int i = 0; i < info.length; i++) { 
        if (info[i].getState() == NetworkInfo.State.CONNECTED) { 
         return true; 

        } 
       } 
      } 
     } 

     return false; 
    } 


    private class RequestTask extends AsyncTask<String, String, String> { 
     // make a request to the specified url 
     @Override 
     protected String doInBackground(String... uri) { 
      HttpClient httpclient = new DefaultHttpClient(); 
      HttpResponse response; 
      String responseString = null; 
      try { 
       // make a HTTP request 
       response = httpclient.execute(new HttpGet(uri[0])); 
       StatusLine statusLine = response.getStatusLine(); 
       if (statusLine.getStatusCode() == HttpStatus.SC_OK) { 
        // request successful - read the response and close the 
        // connection 
        ByteArrayOutputStream out = new ByteArrayOutputStream(); 
        response.getEntity().writeTo(out); 
        out.close(); 
        responseString = out.toString(); 
       } else { 
        // request failed - close the connection 
        response.getEntity().getContent().close(); 
        throw new IOException(statusLine.getReasonPhrase()); 
       } 
      } catch (Exception e) { 
       Log.d("Test", "Couldn't make a successful request!"); 
      } 
      return responseString; 
     } 

     // if the request above completed successfully, this method will 
     // automatically run so you can do something with the response 
     @Override 
     protected void onPostExecute(String response) { 
      super.onPostExecute(response); 

      if (response != null) { 
       try { 
        // convert the String response to a JSON object, 
        // because JSON is the response format Rotten Tomatoes uses 
        JSONObject jsonResponse = new JSONObject(response); 

        // fetch the array of movies in the response 
        movies = jsonResponse.getJSONArray("movies"); 

        // add each movie's title to an array 
        for (int i = 0; i < movies.length(); i++) { 
         JSONObject movie = movies.getJSONObject(i); 
         movieTitles.add(movie.getString("title")); 
        } 

        movieID = new String[movies.length()]; 
        for (int i = 0; i < movies.length(); i++) { 
         JSONObject id = movies.getJSONObject(i); 
         movieID[i] = id.getString("id"); 
        } 


        for (int i = 0; i < movies.length(); i++) { 
         try { 
          JSONObject movie = movies.getJSONObject(i); 
          JSONObject posterurl = movie 
            .getJSONObject("posters"); 
          String audrating = posterurl.get("thumbnail") 
            .toString(); 
          URL newurl = new URL(audrating); 
          Bitmap mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); 
          posterbitmap.add(mIcon_val); 

         } catch (Exception e) { 
          URL newurl = null; 
          try { 
           newurl = new URL("http://www.texomashomepage.biz/images/movie_no_poster.160x240.png"); 
          } catch (MalformedURLException e1) { 
           // TODO Auto-generated catch block 
           e1.printStackTrace(); 
          } 
          Bitmap mIcon_val = null; 
          try { 
           mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); 
          } catch (IOException e1) { 
           // TODO Auto-generated catch block 
           e1.printStackTrace(); 
          } 
          posterbitmap.add(mIcon_val); 
         } 

        } 

        refreshMoviesName(); 
       } catch (JSONException e) { 
        Log.d("Test", "Failed to parse the JSON response!"); 
       } 
      } 
     } 
    } 


    class MyAdapter extends BaseAdapter { 

     @Override 
     public int getCount() { 
      // TODO Auto-generated method stub 
      return movieTitles.size(); 
     } 

     @Override 
     public Object getItem(int arg0) { 
      // TODO Auto-generated method stub 
      return movieTitles.get(arg0); 
     } 

     @Override 
     public long getItemId(int position) { 
      // TODO Auto-generated method stub 
      return position; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      // TODO Auto-generated method stub 
      RelativeLayout rl = (RelativeLayout) getLayoutInflater().inflate(
        R.layout.list_row, parent, false); 
      TextView nametext = (TextView) rl.findViewById(R.id.namelisttext); 
      TextView casttext = (TextView) rl.findViewById(R.id.castlisttext); 
      TextView yeartext = (TextView) rl 
        .findViewById(R.id.releaseyearlisttext); 
      TextView rtscoretext = (TextView) rl.findViewById(R.id.rtscoretext); 
      TextView audscoretext = (TextView) rl 
        .findViewById(R.id.audscoretext); 
      ImageView rtscoreimg = (ImageView) rl.findViewById(R.id.rtscore); 

      ImageView posterimg = (ImageView) rl.findViewById(R.id.poster); 



      int rtscorevalue = Integer.parseInt(rtscore.get(position)); 
      if (rtscorevalue < 50) { 
       rtscoreimg.setImageResource(R.drawable.rotten); 
      } 

      nametext.setText(movieTitles.get(position)); 
      casttext.setText(castnames.get(position)); 
      yeartext.setText(releaseyear.get(position)); 
      audscoretext.setText(audscore.get(position)); 

      if (rtscorevalue == -1) { 
       rtscoretext.setText("Not Available"); 
      } else { 
       rtscoretext.setText(rtscore.get(position)); 
      } 

      final TextView favtext = (TextView) rl.findViewById(R.id.favtext); 
      final ImageView favourite = (ImageView) rl 
        .findViewById(R.id.favourite); 
      favourite.setOnClickListener(new View.OnClickListener() { 

       @Override 
       public void onClick(View arg0) { 
        // TODO Auto-generated method stub 
        if (fav) { 
         favourite.setImageResource(R.drawable.fav_off); 
         fav = false; 
         favtext.setText("Mark as your Favorite Movie"); 
        } else { 
         favourite.setImageResource(R.drawable.fav_on); 
         fav = true; 
         favtext.setText("This is your Favorite Movie"); 
        } 
       } 
      }); 

      return rl; 
     } 

    } 

是什么问题以及如何解决它。这是logcat。

09-23 15:59:28.802: E/AndroidRuntime(27420): FATAL EXCEPTION: main 
09-23 15:59:28.802: E/AndroidRuntime(27420): android.os.NetworkOnMainThreadException 
09-23 15:59:28.802: E/AndroidRuntime(27420): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1128) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at java.net.InetAddress.lookupHostByName(InetAddress.java:385) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at java.net.InetAddress.getAllByName(InetAddress.java:214) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpEngine.connect(HttpEngine.java:311) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:292) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:185) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at tech.know.merge.moviews.InTheaters$RequestTask.onPostExecute(InTheaters.java:298) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at tech.know.merge.moviews.InTheaters$RequestTask.onPostExecute(InTheaters.java:1) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at android.os.AsyncTask.finish(AsyncTask.java:631) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at android.os.AsyncTask.access$600(AsyncTask.java:177) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at android.os.Handler.dispatchMessage(Handler.java:99) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at android.os.Looper.loop(Looper.java:153) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at android.app.ActivityThread.main(ActivityThread.java:5297) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at java.lang.reflect.Method.invokeNative(Native Method) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at java.lang.reflect.Method.invoke(Method.java:511) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 
09-23 15:59:28.802: E/AndroidRuntime(27420): at dalvik.system.NativeStart.main(Native Method) 
+4

切勿按照@SweetWisher的建议更改'ThreadPOlicy'。它在那里向开发人员展示他们做错了什么。在UI线程上做网络是错误的。 – Budius 2014-09-23 10:49:39

回答

-1

在你onPostExecute功能,你有这样的代码在catch块:

URL newurl = null; 
try { 
    newurl = new URL("http://www.texomashomepage.biz/images/movie_no_poster.160x240.png"); 
} catch (MalformedURLException e1) { 
    // TODO Auto-generated catch block 
    e1.printStackTrace(); 
} 

编辑:笑不添加实际的网络操作。 (就在上面的代码之后,你做了实际的请求)

Bitmap mIcon_val = null; 
try { 
    mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); 
} catch (IOException e1) { 
    // TODO Auto-generated catch block 
    e1.printStackTrace(); 
} 
+2

这不是原因。此块上没有网络操作。 – 2014-09-23 10:53:24

+0

无相关答案plz review your answer – praveen 2014-09-23 11:00:20

+0

@BatuhanC让我自己吧。 – 2014-09-23 11:24:33

0

你在onPostExecute里面的主线程。你仍然在那里做网络连接。

mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); 
+0

你能帮忙做些什么? – Akshat 2014-09-23 10:55:08

3

你的问题是在这里:

URL newurl = new URL(audrating); 
Bitmap mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); 
posterbitmap.add(mIcon_val); 

此代码属于“doInBackground”的方法,也许你应该考虑作出的AsyncTask结果的位图,以便在onPostExecute方法,你会得到一个位图并将其设置为ImageView。

+0

你可以请一个小代码帮忙吗?? – Akshat 2014-09-23 10:54:43

+0

基本上,将AsyncTask的第三个参数(返回类型)设置为位图,将处理String的所有代码移动到JSON中,并调用URL以在doInBackground方法中创建位图,然后返回位图而不是字符串。然后,在onPostExecute中,你会得到一个位图 - 用它来设置你想要的任何变量。 – 2014-09-23 10:56:32

相关问题