سؤال

I'm really stumped by the logcat stacktrace (i'm not really familiar with android) whilst creating this basic method to check my device's network bandwidth. The code loads a webpage, times how long it takes, and measures the content downloaded. This value is then divided by the milliseconds that was required to load the webpage to calculate the approximate bandwidth.

Code:

public class MainActivity extends Activity {
private int linkSpeed;
private TextView textView;

/** Called when the activity is created. */

@Override
public void onCreate(Bundle savedInstanceState) {       
    super.onCreate(savedInstanceState);
    textView = new TextView(this);
    textView.setTextSize(25);

  //Download your image
    Thread thread = new Thread(new Runnable() {
        public void run() {
            try {
                String urlString = "http://www.google.com";
                long startTime = System.currentTimeMillis();
                HttpGet httpRequest = new HttpGet(new URL(urlString).toURI());
                HttpClient httpClient = new DefaultHttpClient();
                HttpResponse response = (HttpResponse) httpClient.execute(httpRequest);
                long endTime = System.currentTimeMillis();

                HttpEntity entity = response.getEntity();
                BufferedHttpEntity bufHttpEntity;
                bufHttpEntity = new BufferedHttpEntity(entity);

                //You can re-check the size of your file
                final long contentLength = bufHttpEntity.getContentLength();

                // Log
                String TAG = "tag";
                Log.d(TAG, "[BENCHMARK] Dowload time :"+(endTime-startTime)+" ms");

                // Bandwidth : size(KB)/time(s)
                float bandwidth = contentLength / ((endTime-startTime) *1000);

                textView.setText("bandwidth = " + bandwidth);
                setContentView(textView);
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (URISyntaxException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    });
    thread.start();
}

I'm confused about LOGCAT complaining about being incapable of creating handlers, because I never used one in this class. LOGCAT TRACE:

07-03 14:42:18.214: D/dalvikvm(2401): Late-enabling CheckJNI
07-03 14:42:18.474: D/tag(2401): [BENCHMARK] Dowload time :166 ms
07-03 14:42:18.474: W/dalvikvm(2401): threadid=11: thread exiting with uncaught exception (group=0x4162e930)
07-03 14:42:18.474: E/AndroidRuntime(2401): FATAL EXCEPTION: Thread-201
07-03 14:42:18.474: E/AndroidRuntime(2401): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
07-03 14:42:18.474: E/AndroidRuntime(2401):     at android.os.Handler.<init>(Handler.java:197)
07-03 14:42:18.474: E/AndroidRuntime(2401):     at android.os.Handler.<init>(Handler.java:111)
07-03 14:42:18.474: E/AndroidRuntime(2401):     at com.android.internal.app.ActionBarImpl.<init>(ActionBarImpl.java:108)
07-03 14:42:18.474: E/AndroidRuntime(2401):     at android.app.Activity.initActionBar(Activity.java:1867)
07-03 14:42:18.474: E/AndroidRuntime(2401):     at android.app.Activity.setContentView(Activity.java:1902)
07-03 14:42:18.474: E/AndroidRuntime(2401):     at com.example.networkinfo.MainActivity$1.run(MainActivity.java:69)
07-03 14:42:18.474: E/AndroidRuntime(2401):     at java.lang.Thread.run(Thread.java:856)
07-03 14:42:18.524: D/dalvikvm(2401): GC_CONCURRENT freed 232K, 5% free 7525K/7912K, paused 9ms+2ms, total 50ms
07-03 14:42:18.894: D/libEGL(2401): loaded /system/lib/egl/libEGL_tegra.so
07-03 14:42:18.914: D/libEGL(2401): loaded /system/lib/egl/libGLESv1_CM_tegra.so
07-03 14:42:18.924: D/libEGL(2401): loaded /system/lib/egl/libGLESv2_tegra.so
07-03 14:42:18.944: D/OpenGLRenderer(2401): Enabling debug mode 0
هل كانت مفيدة؟

المحلول

This line

textView.setText("bandwidth = " + bandwidth);

is giving you trouble. You are trying to update the UI on a background Thread. You need to either make it an AsyncTask and update the UI in a method other than doInBackground() or use runOnUiThread()

Here is an example of using runOnUiThread()

and one of AsyncTask

AsyncTask Docs

نصائح أخرى

You can't call setContentView from a non-UI thread. My sugestion is to convert that thread to an AsyncTask and set the content view in onPostExecute. The same problem exists in your setText call.

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

You cannot call setContentView() from a background thread. Moreover, you need to show some UI when your activity launches, rather than waiting for an HTTP operation that may never complete successfully.

Instead, call setContentView() before doing background work. In particular, consider using an AsyncTask instead of a Thread, and updating your widgets with the results of the HTTP operation (if successful) in onPostExecute().

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top