質問

A part of my app includes going to a webpage and parsing its text to get a Bible Verse of the Day. For the main app, I have tossed the code into an ASyncTask and it works great, but I am trying to get it so that I can do the same thing in a Broadcast Receiver and am having issues. I have copied the code from the doInBackground() method and set up the following method. The only changes I have made were to directly save the gathered data when it was found as opposed to storing them in temporary variables to be handled in the onPostExecute() method.

public void getVOTD() {
    BufferedReader in = null;
    try {
        HttpClient client = new DefaultHttpClient();
        URI website = new URI("http://verseoftheday.com");
        HttpGet request = new HttpGet();
        request.setURI(website);
        HttpResponse response = client.execute(request);
        response.getStatusLine().getStatusCode();

        in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer sb = new StringBuffer("");
        String l = "";
        String nl = System.getProperty("line.separator");

        //Read line by line, looking for the sepcific lines on the webpage
        while((l = in.readLine()) != null) {
            sb.append(l + nl);

            if(l.contains("og:title")) {
                ref.setText(l.substring(55, l.length() - 4));
                Toast.makeText(context, ref.getText().toString(), Toast.LENGTH_SHORT).show();
            }
            else if(l.contains("og:description")) {
                String des = l.substring(43,l.length() - 4);
                des = des.replaceAll(""", "\"");
                des = des.replaceAll("'", "'");
                des = des.replaceAll("—", "--");
                ver.setText(des);
                Toast.makeText(context, ver.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        }
        in.close();             
    }
    catch(Exception e) {
        e.printStackTrace();
        ref.setText("Error");
        ver.setText(e.getMessage());
    }
    finally {
        if(in != null) {
            try {
                in.close();
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
}

The problem is that this method throws an exception as soon as it tries to read a line. The exception has no message, but I get the following stack trace:

05-14 13:54:19.288: W/System.err(23789): android.os.NetworkOnMainThreadException
0

5-14 13:54:19.288: W/System.err(23789):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
05-14 13:54:19.298: W/System.err(23789):    at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
05-14 13:54:19.298: W/System.err(23789):    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
05-14 13:54:19.298: W/System.err(23789):    at java.net.InetAddress.getAllByName(InetAddress.java:214)
05-14 13:54:19.298: W/System.err(23789):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
05-14 13:54:19.298: W/System.err(23789):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
05-14 13:54:19.298: W/System.err(23789):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
05-14 13:54:19.298: W/System.err(23789):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
05-14 13:54:19.298: W/System.err(23789):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
05-14 13:54:19.298: W/System.err(23789):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
05-14 13:54:19.298: W/System.err(23789):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
05-14 13:54:19.298: W/System.err(23789):    at com.caseybrooks.scripturememory.views.VOTDCard.getVOTD(VOTDCard.java:85)
05-14 13:54:19.298: W/System.err(23789):    at com.caseybrooks.scripturememory.views.VOTDCard.initialize(VOTDCard.java:74)
05-14 13:54:19.298: W/System.err(23789):    at com.caseybrooks.scripturememory.views.VOTDCard.<init>(VOTDCard.java:50)
05-14 13:54:19.298: W/System.err(23789):    at com.caseybrooks.scripturememory.fragments.DashboardFragment.initialize(DashboardFragment.java:76)
05-14 13:54:19.298: W/System.err(23789):    at com.caseybrooks.scripturememory.fragments.DashboardFragment.onCreateView(DashboardFragment.java:50)
05-14 13:54:19.298: W/System.err(23789):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
05-14 13:54:19.298: W/System.err(23789):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
05-14 13:54:19.298: W/System.err(23789):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
05-14 13:54:19.298: W/System.err(23789):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
05-14 13:54:19.298: W/System.err(23789):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
05-14 13:54:19.298: W/System.err(23789):    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:570)
05-14 13:54:19.298: W/System.err(23789):    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1164)
05-14 13:54:19.298: W/System.err(23789):    at android.app.Activity.performStart(Activity.java:5114)
05-14 13:54:19.298: W/System.err(23789):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2271)
05-14 13:54:19.298: W/System.err(23789):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2358)
05-14 13:54:19.298: W/System.err(23789):    at android.app.ActivityThread.access$600(ActivityThread.java:153)
05-14 13:54:19.298: W/System.err(23789):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
05-14 13:54:19.298: W/System.err(23789):    at android.os.Handler.dispatchMessage(Handler.java:99)
05-14 13:54:19.298: W/System.err(23789):    at android.os.Looper.loop(Looper.java:137)
05-14 13:54:19.298: W/System.err(23789):    at android.app.ActivityThread.main(ActivityThread.java:5227)
05-14 13:54:19.298: W/System.err(23789):    at java.lang.reflect.Method.invokeNative(Native Method)
05-14 13:54:19.298: W/System.err(23789):    at java.lang.reflect.Method.invoke(Method.java:511)
05-14 13:54:19.298: W/System.err(23789):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
05-14 13:54:19.298: W/System.err(23789):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
05-14 13:54:19.298: W/System.err(23789):    at dalvik.system.NativeStart.main(Native Method)
05-14 13:54:19.368: D/libEGL(23789): loaded /system/lib/egl/libEGL_adreno200.so
05-14 13:54:19.368: D/libEGL(23789): loaded /system/lib/egl/libGLESv1_CM_adreno200.so
05-14 13:54:19.368: D/libEGL(23789): loaded /system/lib/egl/libGLESv2_adreno200.so
05-14 13:54:19.378: I/Adreno200-EGL(23789): <qeglDrvAPI_eglInitialize:269>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_JB_VANILLA.04.02.02.60.051_msm8960_JB_VANILLA_CL2997615_release_AU (CL2997615)
05-14 13:54:19.378: I/Adreno200-EGL(23789): Build Date: 04/11/13 Thu
05-14 13:54:19.378: I/Adreno200-EGL(23789): Local Branch: 
05-14 13:54:19.378: I/Adreno200-EGL(23789): Remote Branch: quic/mako_jb_mr1
05-14 13:54:19.378: I/Adreno200-EGL(23789): Local Patches: NONE
05-14 13:54:19.378: I/Adreno200-EGL(23789): Reconstruct Branch: AU_LINUX_ANDROID_JB_VANILLA.04.02.02.60.051 +  NOTHING
05-14 13:54:19.398: E/(23789): <s3dReadConfigFile:75>: Can't open file for reading
05-14 13:54:19.398: E/(23789): <s3dReadConfigFile:75>: Can't open file for reading
05-14 13:54:19.398: E/(23789): <s3dReadConfigFile:75>: Can't open file for reading
05-14 
13:54:19.398: D/OpenGLRenderer(23789): Enabling debug mode 0

What am I doing wrong here?

役に立ちましたか?

解決

The problem you have is that you are trying to do the networking from the main thread. That is the reason you got this Exception:

NetworkOnMainThreadException

The exception that is thrown when an application attempts to perform a networking operation on its main thread.

==> stick to your first idea and keep doing that from an AsyncTask to keep your app responsive. This counts also for BroadcastReceivers, see this guide here:

The specific constraint on BroadcastReceiver execution time emphasizes what broadcast receivers are meant to do: small, discrete amounts of work in the background such as saving a setting or registering a Notification. So as with other methods called in the UI thread, applications should avoid potentially long-running operations or calculations in a broadcast receiver.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top