我创建了一个位图数组,我正在listview中的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)
答案 0 :(得分:3)
你的问题在这里:
URL newurl = new URL(audrating);
Bitmap mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream());
posterbitmap.add(mIcon_val);
这段代码属于“doInBackground”方法,也许您应该考虑将AsyncTask的结果作为位图,这样在onPostExecute方法中,您只需获取一个位图并将其设置为ImageView。
答案 1 :(得分:0)
你在onPostExecute里面的主线程上。你还在那里做网络连接。
mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream());
答案 2 :(得分:-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();
}
编辑:lol没有添加实际的网络操作。 (在上面的代码之后,你做了实际的请求)
Bitmap mIcon_val = null;
try {
mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}