IntentService android.os.NetworkOnMainThreadException

时间:2013-11-28 19:49:13

标签: android

每当我收到短信时,我想在网络上发布广播侦听器调用IntentService方法,但它会给我以下错误

Activity stop timeout for ActivityRecord{420eec20 u0 com.example.myapp/.LoginActivity}

11-29 00:03:23.486   W/System.err﹕ android.os.NetworkOnMainThreadException

11-29 00:03:23.591   W/System.err﹕ at
 android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)

11-29 00:03:23.596   I/dalvikvm﹕ Wrote stack traces to '/data/anr/traces.txt'

11-29 00:03:23.596   W/System.err﹕ at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)

11-29 00:03:23.601   W/System.err﹕ at libcore.io.IoBridge.connectErrno(IoBridge.java:127)

11-29 00:03:23.606   W/System.err﹕ at libcore.io.IoBridge.connect(IoBridge.java:112)

11-29 00:03:23.611   W/System.err﹕ at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)

11-29 00:03:23.616   W/System.err﹕ at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)

我知道在服务中我们因为mainthread而无法使用互联网漫长的进程 但是,intentservice是独立的让我展示代码

主要活动

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);

    setContentView(R.layout.activity_main);

    final Intent intent = new Intent(this,AndroService.class);

    this.startService(intent);

}

服务类

            import org.json.JSONException;
            import org.json.JSONObject;

            public class AndroService extends IntentService
            {

                UsrAction upPayload;
                private String smsURL = "exampleurl";
                private HttpClientClass usrpayloader;

                public AndroService() {
                    super("MyApp");
                }

                public AndroService(String name) {
                    super("MyApp");
                }

                @Override
                protected void onHandleIntent(Intent intent) {
                    Toast.makeText(this, "Service started", Toast.LENGTH_SHORT).show();
                }

                @Override
                public int onStartCommand(Intent intent, int flags, int startId) {
                    onHandleIntent(intent);
                    return 1;
                }


                public enum RequestMethod
                {
                 GET,POST
                }

                public void smspayload(Context context, String strBody)
                {
                    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
                    String cookievalue = sharedPreferences.getString("androsession", null);

                    usrpayloader.AddParam("smsbody", strBody);
                    usrpayloader.AddHeader(cookievalue,"value");


                    try {
                        usrpayloader.Execute(RequestMethod.POST);
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                    String fetchdata = usrpayloader.getResponse();
                    try {
                        JSONObject json = new JSONObject(fetchdata);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }

BroadcastReceiver类

                import android.content.BroadcastReceiver;
                import android.content.Context;
                import android.content.Intent;
                import android.os.Bundle;
                import android.telephony.SmsMessage;
                import android.util.Log;
                import android.widget.Toast;

                public class broadcaster extends BroadcastReceiver
                {
                    private final String TAG = "Hello";
                    private HttpClientClass usrpayloader;
                    private AndroService servusr;

                    @Override
                    public void onReceive(Context context, Intent intent)
                    {
                        Bundle extras = intent.getExtras();

                        String strMessage = "";
                        String strSrc="";
                        String strBody ="";
                        long time = 0;

                        if ( extras != null )
                        {
                            Object[] smsextras = (Object[]) extras.get( "pdus" );

                            for ( int i = 0; i < smsextras.length; i++ )
                            {
                                SmsMessage smsmsg = SmsMessage.createFromPdu((byte[])smsextras[i]);

                                String strMsgBody = smsmsg.getMessageBody().toString();
                                String strMsgSrc = smsmsg.getOriginatingAddress();

                                strSrc = strMsgSrc;
                                strBody = strMsgBody;
                                time = smsmsg.getTimestampMillis();
                                strMessage += "SMS from " + strMsgSrc + " : " + strMsgBody;

                                Log.i(TAG, strMessage);
                            }

                            Toast.makeText(context,strMessage,Toast.LENGTH_SHORT).show();
                            servusr = new AndroService();
                            servusr.smspayload(context,strBody,strSrc,time);

                        }

                    }

                }

问题是如何通过 android.os.NetworkOnMainThreadException 错误 我想使用intentservice方法,所以将对象声明为broadcastreceiver是一种很好的做法吗?

1 个答案:

答案 0 :(得分:2)

您没有正确使用IntentService

首先,永远不要通过构造函数自己创建Service的实例。您可以通过startService()bindService()启动服务。在IntentService的情况下,startService()是典型方法。

其次,smspayload()需要调用onHandleIntent()才能在IntentService提供的后台线程上处理strBody。要将数据传递给它,请将Intent作为额外内容打包到startService()onHandleIntent()。然后,getStringExtra()可以致电Intent上的smspayload()来检索参数并将其传递给Context。您可以删除smspayload()上的context参数,并将this替换为Service,因为Context是{{1}}。