我得到了一些stackflower的代码,由于某种原因,它崩溃了我的应用程序,是Async的新手,我没有很多调试经验。我尝试从HttPost下载数据,然后在简单的列表视图中列出数据。无论如何,这里是代码和logcat:
代码:
public class ChatService extends ListActivity {
/** Called when the activity is first created. */
BufferedReader in = null;
String data = null;
List headlines;
List links;
String GotPass;
ArrayAdapter adapter;
String GotUname;
public static final String PREFS_NAME ="MyPregs";
private GetTask getTask;
public ListView fList;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getTask = new GetTask();
getTask.execute();
ArrayAdapter adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1, headlines);
}
public class GetTask extends AsyncTask<Void, Void, List>
{
@Override
protected List doInBackground(Void... params) {
return load();
}
@Override
protected void onPostExecute(List result) {
fList.setAdapter(adapter);
}
}
private List load() {
// get your data from http
// add to your list, probably you can use model.
BufferedReader in = null;
String data = null;
Bundle gotData = getIntent().getExtras();
if(gotData != null)
{
GotPass = gotData.getString("key!");
GotUname = gotData.getString("key!!");
}
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String username = settings.getString("key1", null);
String password = settings.getString("key2", null);
if(username.equals("irock97")) {
Toast.makeText(getApplicationContext(), "yaya", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "fail", Toast.LENGTH_SHORT).show();
}
HttpClient httpclient = new DefaultHttpClient();
/* login.php returns true if username and password is equal to saranga */
HttpPost httppost = new HttpPost("http://gta5news.com/login.php");
try {
// Add user name and password
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", username));
nameValuePairs.add(new BasicNameValuePair("password", password));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
Log.w("HttpPost", "Execute HTTP Post Request");
HttpResponse response = httpclient.execute(httppost);
in = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent()));
StringBuffer sb = new StringBuffer("");
String l ="";
String nl ="";
while ((l =in.readLine()) !=null) {
sb.append(l + nl);
}
in.close();
data = sb.toString();
ListView lv = getListView();
lv.setTextFilterEnabled(true);
headlines.add(data);
ArrayAdapter adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1, headlines);
setListAdapter(adapter);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return headlines;
}
private StringBuilder inputStreamToString1(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
// Wrap a BufferedReader around the InputStream
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// Read response until the end
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Return full string
return total;
}
}
logcat的:
04-10 20:47:18.526: E/AndroidRuntime(574): FATAL EXCEPTION: AsyncTask #1
04-10 20:47:18.526: E/AndroidRuntime(574): java.lang.RuntimeException: An error occured while executing doInBackground()
04-10 20:47:18.526: E/AndroidRuntime(574): at android.os.AsyncTask$3.done(AsyncTask.java:200)
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
04-10 20:47:18.526: E/AndroidRuntime(574): at java.lang.Thread.run(Thread.java:1096)
04-10 20:47:18.526: E/AndroidRuntime(574): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-10 20:47:18.526: E/AndroidRuntime(574): at android.os.Handler.<init>(Handler.java:121)
04-10 20:47:18.526: E/AndroidRuntime(574): at android.widget.Toast.<init>(Toast.java:68)
04-10 20:47:18.526: E/AndroidRuntime(574): at android.widget.Toast.makeText(Toast.java:231)
04-10 20:47:18.526: E/AndroidRuntime(574): at com.gta5news.bananaphone.ChatService.load(ChatService.java:97)
04-10 20:47:18.526: E/AndroidRuntime(574): at com.gta5news.bananaphone.ChatService.access$0(ChatService.java:82)
04-10 20:47:18.526: E/AndroidRuntime(574): at com.gta5news.bananaphone.ChatService$GetTask.doInBackground(ChatService.java:71)
04-10 20:47:18.526: E/AndroidRuntime(574): at com.gta5news.bananaphone.ChatService$GetTask.doInBackground(ChatService.java:1)
04-10 20:47:18.526: E/AndroidRuntime(574): at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-10 20:47:18.526: E/AndroidRuntime(574): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
答案 0 :(得分:2)
You are calling Toast in load() function which is in DoInBackground.
Toast messages touches UI thread which you can't do that.
This line makes it crash.
Toast.makeText(getApplicationContext(), "yaya", Toast.LENGTH_SHORT).show();
Change you load function signature:
This is your function:
private List load() {
don't return a list, create a modal container and return it like:
private ReturnModel load() {
and create a modal like this, and set and get this modal:
and in your load function,fill this returnmodal, set passworderror true or false instead of toast message, and onpostexecute function, check password error and do your toast message there.
package com.nesim.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import android.app.ListActivity;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class ChatService extends ListActivity {
String GotPass;
String GotUname;
public static final String PREFS_NAME = "MyPregs";
private GetTask getTask;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getTask = new GetTask();
getTask.execute();
}
public class GetTask extends AsyncTask<Void, Void, ReturnModel> {
@Override
protected ReturnModel doInBackground(Void... params) {
return load();
}
@Override
protected void onPostExecute(ReturnModel result) {
if(result.passworderror == true)
{
Toast.makeText(getApplicationContext(), "fail", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(), "yaya", Toast.LENGTH_SHORT).show();
ListView lv = getListView();
lv.setTextFilterEnabled(true);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, result.getheadlines());
setListAdapter(adapter);
}
}
}
private ReturnModel load() {
ReturnModel returnModel = new ReturnModel();
BufferedReader in = null;
String data = null;
Bundle gotData = getIntent().getExtras();
if (gotData != null) {
GotPass = gotData.getString("key!");
GotUname = gotData.getString("key!!");
}
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String username = settings.getString("key1", null);
String password = settings.getString("key2", null);
// username = "irock97"; // unremark to test like you got username from prefs..
if (username != null && username.equals("irock97")) {
returnModel.setPassworderror(false);
}
else
{
returnModel.setPassworderror(true);
return returnModel;
}
HttpClient httpclient = new DefaultHttpClient();
/* login.php returns true if username and password is equal to saranga */
HttpPost httppost = new HttpPost("http://gta5news.com/login.php");
try {
// Add user name and password
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", username));
nameValuePairs.add(new BasicNameValuePair("password", password));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
Log.w("HttpPost", "Execute HTTP Post Request");
HttpResponse response = httpclient.execute(httppost);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = "";
while ((l = in.readLine()) != null) {
sb.append(l + nl);
}
in.close();
data = sb.toString();
List<String> headlines = new ArrayList<String>();
headlines.add(data);
returnModel.setheadlines(headlines);
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return returnModel;
}
public class ReturnModel {
private List<String> headlines;
private boolean passworderror;
public List<String> getheadlines() {
return headlines;
}
public void setheadlines(List<String> headlines) {
this.headlines = headlines;
}
public boolean getPassworderror() {
return passworderror;
}
public void setPassworderror(boolean passworderror) {
this.passworderror = passworderror;
}
}
}
答案 1 :(得分:0)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
在doInbackground()
中调用Looper.Prepare()编辑:还要确保在UI线程上运行Toast,就像其他人都注意到的那样。
答案 2 :(得分:0)
当您尝试修改UI线程外部的UI时,通常会发生此错误。您看到的错误是由Toast.makeText()
电话引起的。您可以将其重写为:
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText( /* etc */).show();
}
}
答案 3 :(得分:0)
您正在调用Toast.makeText
而不是在主UI线程中。
因为它写在堆栈跟踪中:
无法在未调用Looper.prepare()的线程内创建处理程序。 在内部,Toast.makeText正在创建自己使用的处理程序。
如果这是出于测试目的,您最好使用Log.v或类似的。
如果你想真正制作Toasts,那么尝试使用runOnUIThread()或更好:
publishProgress(...);
和
onProgressUpdate()
可从AsyncTasks获得。