0

我正在尝试从 HttpPost 下载字符串,并且正在使用 Async 类来执行此操作。但是,当我运行该应用程序时,它崩溃了。这是我第一次使用 Async 类,恐怕我做了一些很傻的事情,你能帮我找出错误吗?

请注意,我还想在获取字符串时更新我的​​列表视图。我试图这样做,购买将它们放在单独的方法中。

代码:

public static final String PREFS_NAME = "MyPrefsFile";
    BufferedReader in = null;
    String data = null;
    String username;
    List headlines;
    List links;
    String password;
    ArrayAdapter adapter;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
            // listview method
            ContactsandIm();
        new loadcontactsandIm().execute(PREFS_NAME);

    }

    public class loadcontactsandIm extends AsyncTask<String, Integer, String> {
        @Override
        protected String doInBackground(String... arg0) {
            // TODO Auto-generated method stub

            // Create a new HttpClient and Post Header
            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 {

                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);
                Log.w("HttpPost", "Execute HTTP Post Request");
                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);




                setListAdapter(adapter);
                return null;

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return data;
        }

        private StringBuilder inputStreamToString(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;
        }

        }


    public void ContactsandIm() {
        headlines = new ArrayList();

        //get prefs
        SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
        String username = settings.getString("key1", null);
        String password = settings.getString("key2", null);
        if(username.equals("irock97"))  {
            Toast toast=Toast.makeText(this, "Hello toast", 2000);
            toast.setGravity(Gravity.TOP, -30, 50);
            toast.show();

        } else {
            Toast toast=Toast.makeText(this, "Hello toast", 2000);
            toast.setGravity(Gravity.TOP, -30, 150);
            toast.show();
        }
        ArrayAdapter adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_1, headlines);


    }

}

日志猫:

03-25 13:47:37.356: E/AndroidRuntime(2484): FATAL EXCEPTION: AsyncTask #1
03-25 13:47:37.356: E/AndroidRuntime(2484): java.lang.RuntimeException: An error occured while executing doInBackground()
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.lang.Thread.run(Thread.java:1096)
03-25 13:47:37.356: E/AndroidRuntime(2484): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.ViewRoot.requestLayout(ViewRoot.java:594)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.View.requestLayout(View.java:8125)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.View.requestLayout(View.java:8125)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.View.requestLayout(View.java:8125)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.ViewGroup.removeAllViews(ViewGroup.java:2255)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:196)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.app.Activity.setContentView(Activity.java:1647)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.app.ListActivity.ensureList(ListActivity.java:314)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.app.ListActivity.getListView(ListActivity.java:299)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at com.gta5news.bananaphone.ChatService$loadcontactsandIm.doInBackground(ChatService.java:87)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at com.gta5news.bananaphone.ChatService$loadcontactsandIm.doInBackground(ChatService.java:1)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
4

4 回答 4

2

您在 doInBackground 中设置 ListView 适配器。永远不要在 UI 线程之外操作 UI

于 2012-04-08T15:02:33.490 回答
2

您不能与主线程以外的任何其他线程中的 UI 元素进行交互。您需要在onPostExecute方法中完成 ListView 的所有交互。

基本上,您将希望在 doInBackground 方法中编译来自 Web 请求的所有数据,存储在您的任务实例中,然后在 onPostExecute 上获取列表视图并设置适配器并使用数据填充。

于 2012-04-08T15:03:21.130 回答
2

你在 doInBackground 工作吗,并在 onPostExecute 上使用你的工作结果。

例子:

public class TestActivity extends Activity 
{
  private GetTask getTask;
  public ListView fList;

  @Override
  public void onCreate(Bundle savedInstanceState) 
  {
    getTask = new GetTask(); 
    getTask.execute();
    fList = (ListView) findViewById(R.id.lstview);
  }

  public class GetTask extends AsyncTask<Void, Void, List> 
  {
    @Override
    protected List doInBackground(Void... params) {
      return load();
    }      

    @Override
    protected void onPostExecute(List result) {
        ArrayAdapter adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_1, headlines);

      fList.setAdapter(adapter);
    }
  }

  private List load() { 
    // get your data from http
    // add to your list, probably you can use model.
    List headlines;
    headlines.add(data);

    return headlines;
  }


}
于 2012-04-08T20:59:39.037 回答
1

首先,您不能在 doInBackground() 中处理任何 UI 相关任务到 UI 相关任务,我们有一个方法调用 onPostExecute() ,我们可以在其中处理所有与 ui 相关的任务。如果您仍然不想使用这些方法并在 doInBackground( ) 然后你在下面的代码中执行它::::

runOnUiThread(new Runnable() {
public void run() {
//your UI related code stuff    
    ListView lv = getListView();
    lv.setTextFilterEnabled(true);
    headlines.add(data);
    setListAdapter(adapter); //do what you like here
}
});
于 2012-04-08T16:02:32.737 回答