Sunday, April 29, 2012

StrictMode.setThreadPolicy and StrictMode.ThreadPolicy.Builder


It was described in last exercise "android.os.NetworkOnMainThreadException"; if you access Network (or Disk read/write) in UI thread, with minSdkVersion targeting the Honeycomb or higher, exception will be thrown. And the solution of using AsyncTask was provided in the exercise.

Here is another un-recommended approach: change StrictMode Policy.

StrictMode is a developer tool which detects things you might be doing by accident and brings them to your attention so you can fix them. StrictMode is most commonly used to catch accidental disk or network access on the application's main thread, UI thread.

Using StrictMode.ThreadPolicy.Builder, you can create your own StrictMode.ThreadPolicy, to permit or apply penalty to detected problems:
  • penaltyDeath(): Crash the whole process on violation.
  • penaltyDeathOnNetwork(): Crash the whole process on any network usage.
  • penaltyDialog(): Show an annoying dialog to the developer on detected violations, rate-limited to be only a little annoying.
  • penaltyDropBox(): Enable detected violations log a stacktrace and timing data to the DropBox on policy violation.
  • penaltyFlashScreen(): Flash the screen during a violation.
  • penaltyLog(): Log detected violations to the system log.

It's a example to change thread policy for Network operation, show an annoying dialog, and permit.


package com.exercise.AndroidInternetTxt;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.widget.TextView;

public class AndroidInternetTxt extends Activity {
 
 TextView textMsg, textPrompt;
 final String textSource = "http://sites.google.com/site/androidersite/text.txt";


   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       textPrompt = (TextView)findViewById(R.id.textprompt);
       textMsg = (TextView)findViewById(R.id.textmsg);
      
       textPrompt.setText("Wait...");
       
       StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
       .detectNetwork() // or .detectAll() for all detectable problems
       .penaltyDialog()  //show a dialog
       //.permitNetwork() //permit Network access 
       .build());
      
       URL textUrl;

       try {
        textUrl = new URL(textSource);

        BufferedReader bufferReader 
         = new BufferedReader(new InputStreamReader(textUrl.openStream()));
        
        String StringBuffer;
        String stringText = "";
        while ((StringBuffer = bufferReader.readLine()) != null) {
         stringText += StringBuffer;   
        }
        bufferReader.close();

        textMsg.setText(stringText);
       } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        textMsg.setText(e.toString());   
       } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        textMsg.setText(e.toString());   
       }
  
       textPrompt.setText("Finished!");    
   }

}


Download the files.

1 comment:

Nolesh said...

Cool. That's exactly what I want! I know about asyncTask, but I need to implement sync connection. So I'll use this snippet!