如何在Android中处理networkonmainthreadexception?

时间:2013-01-10 09:38:13

标签: android

我有以下2课

class CallNetworkMethod extends AsyncTask<Void, Void, Void>
{

    @Override
    protected Void doInBackground(Void... params) {

        if (TwitterUtils.isAuthenticated(prefs)) {
            sendTweet();
        } else {

            Intent i = new Intent(getApplicationContext(), TwPrepareRequestTokenActivity.class);
            i.putExtra("tweet_msg",getTweetMsg());
            startActivity(i);
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {

        // TODO Auto-generated method stub
        super.onPostExecute(result);
        //updateLoginStatus();
        loginStatus.setText("Logged into Twitter : " + TwitterUtils.isAuthenticated(prefs));
    }

}

=============================================== =====

public class TwitterUtils {

static ArrayList<String> friens=null;

public static boolean isAuthenticated(SharedPreferences prefs) {

    String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
    String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");

    AccessToken a = new AccessToken(token,secret);
    Twitter twitter = new TwitterFactory().getInstance();

    twitter.setOAuthConsumer(TwConstants.CONSUMER_KEY, TwConstants.CONSUMER_SECRET);

    twitter.setOAuthAccessToken(a);


    try {



        **twitter.getAccountSettings();**

        return true;
    } catch (TwitterException e) {
        return false;
    }
}

}

运行此代码时遇到异常(networkonmainthreadexception)。我调试此代码并找到异常出现的位置。它是 twitter.getAccountSettings(); 。我认为这个方法应该在AsynTask中运行,但我不知道该怎么做。

4 个答案:

答案 0 :(得分:1)

问题是您使用的是AsyncTask错误。 onBackground返回值和onPostExecute接收结果的想法是将后台线程上完成的内容传递给UI线程。

类似的东西:

class CallNetworkMethod extends AsyncTask<Void, Void, Void>更改为

class CallNetworkMethod extends AsyncTask<Void, Void, Boolean>

protected Void doInBackground(Void... params) {更改为

protected Boolean doInBackground(Void... params) {

   Boolean result = TwitterUtils.isAuthenticated(prefs);
        if (result) {
        sendTweet();
    } else {

        Intent i = new Intent(getApplicationContext(), TwPrepareRequestTokenActivity.class);
        i.putExtra("tweet_msg",getTweetMsg());
        startActivity(i);
    }
    return result;       
}

并将protected void onPostExecute(Void result) {更改为

protected void onPostExecute(Boolean result) {
    loginStatus.setText("Logged into Twitter : " + result.toString());
}

答案 1 :(得分:1)

目前您正在TwitterUtils.isAuthenticated(prefs)中调用onPostExecute,因为onPostExecute始终在UI线程上执行,然后您将获得networkonmainthreadexception例外。

要避免此问题,请使用Boolean Flag从doInBackground返回并在onPostExecute的TextView中显示为:

class CallNetworkMethod extends AsyncTask<Void, Void, Void>
{
  public static boolean status=false;
    @Override
    protected Void doInBackground(Void... params) {

       status=TwitterUtils.isAuthenticated(prefs);

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {

        // TODO Auto-generated method stub
        super.onPostExecute(result);
        //updateLoginStatus();
        loginStatus.setText("Logged into Twitter : " + status);
    }

}

答案 2 :(得分:0)

Note that this method blocks waiting for a network response, so do not call it in a UI thread.

这是使用时的建议:

facebook.request("me");

同样可能是这样的:

twitter.getAccountSettings();

因此,就像您使用AsyncTasks调用的其他网络连接一样,在一些AsyncTask中调用它。

好的,错误可能就在这里:

@Override
    protected void onPostExecute(Void result) {

        // TODO Auto-generated method stub
        super.onPostExecute(result);
        //updateLoginStatus();
        loginStatus.setText("Logged into Twitter : " + TwitterUtils.isAuthenticated(prefs));
    }

您正在TwitterUtils.isAuthenticated(prefs)

中呼叫onPostExecute();

答案 3 :(得分:0)

您对isAuthenticated()的第一次调用正确放在AsyncTask中。但是,当您使用:

loginStatus.setText("Logged into Twitter : " + TwitterUtils.isAuthenticated(prefs));

在你的onPostExecute()中,你再次在UI线程上调用一个网络方法,因为onPostExecute()在UI线程上运行。

删除此行,或在doInBackground()本地存储结果并在此处使用。