Search This Blog

Wednesday 30 May 2012

Auto screen size Link

Tuesday 8 May 2012

Worker thread


Worker thread

Worker threads are background threads. They are the threads that are created separately, other than the UI thread. Since blocking the UI thread is restricted according to the rule, user should run the child processes and tasks in worker threads. 

An example for creation and working of worker thread is given below:

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            Bitmap b = loadImageFromNetwork("http://example.com/image.png");
            mImageView.setImageBitmap(b);
        }
    }).start();
}

In the above example code, the download operation is handled by a second thread other than the UI thread. But the program violates the second rule. The imageView from UI thread is manipulating from this worker thread.

According to the second rule, UI could not be accessed from outside the UI thread. Solution for such a restriction is runOnUiThread(Runnable) method. The main or UI thread can be accessed from other threads using runOnUiThread(Runnable) method.
As a result, the specified runnable action passed through this method will run on the UI thread. The action will execute immediately, if the current thread is in the UI itself. Else the action will be posted to the event queue.

An example code:

MainClassName.this.runOnUiThread(new Runnable() {
                    public void run() {
                        textViewObject.setText("Set this " + value from worker thread + "!");
                    }
                });

Only using the methods like runOnUiThread(Runnable), the program can touch the UI views.

Handlers and Runnable

A better solution to process the messages delivered from the UI thread is handlers. The runnable objects can also be processed using the handlers. Runnable is a command that can be executed. It is used to run the code in other thread.

An example that users handlers and runnable objects in worker thread is given here;

WorkerThreadActivity.class

package com.febi.worker;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

public class WorkerThreadActivity extends Activity{
          ImageView image;
          String url="http://icons.iconarchive.com/icons/icons-land/sport/256/Soccer-Ball-icon.png";
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main); 
    }
    public void onClick(View v){ 
        final Handler threadHandler; 
        final Context cbt; 
         
        cbt = this; 
        threadHandler = new Handler(); 
         
        new Thread(new Runnable() { 
            @Override 
            public void run() {
                  
                threadHandler.post(new Runnable() { 
                    @Override 
                    public void run() { 
//                        
                            
                             InputStream is = null;
                             try{
                             URL ulrn = new URL(url);
                        HttpURLConnection con = (HttpURLConnection)ulrn.openConnection();
                        is = con.getInputStream();
                             }catch(Exception e)
                             {
                                      Log.i("LOGCAT Run", ""+e);
                             }
                        Bitmap bmp = BitmapFactory.decodeStream(is);

                            
                             ImageView image=(ImageView)findViewById(R.id.imageView1);
                             image.setImageBitmap(bmp);
                    } 
                }); 
            } 
        }).start();
       
      AlertDialog.Builder ab = new AlertDialog.Builder(cbt); 
      ab.setMessage("A message sent from UI thread"); 
      ab.show();
    } 
         
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
   
    <Button android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="Click Me"
        android:onClick="onClick"
        />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</LinearLayout>

Set permission for Internet in manifest file ;

<uses-permission android:name="android.permission.INTERNET"/>

JSON Parsing


JSON Parsing

JSON is JavaScript Object Notation. JSON parsing is the most comfort and straightforward method to parse responses from web services. It is also a better option other than the xml parsing method.

A sample example that parses the data from a web server; http://api.androidhive.info/contacts/ is given below. This program fetches and parses only name and email data from the web.
JSONParsingExample.class

package php.sql;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class JSONParsingExample  extends Activity
{
          InputStream is;
          String result = "";
          String data = "";
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    public void click(View v)
    {

        //http post
        try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost("http://api.androidhive.info/contacts/");
                //httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
        }catch(Exception e){
                Log.e("log_tag", "Error in http connection "+e.toString());
        }
       
        //convert response to string
        try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                        sb.append(line + "\n");
                }
                is.close();
          
                result=sb.toString();
        }catch(Exception e){
                Log.e("log_tag", "Error converting result "+e.toString());
        }
         
        //parse json data
        try{
     
         
          JSONObject jObj = new JSONObject(result);
          JSONArray jArray =jObj.getJSONArray("contacts");
              //JSONArray jArray = new JSONArray(result);
               
                for(int i=0;i<jArray.length();i++){
                        JSONObject json_data = jArray.getJSONObject(i);
                     
                        String std=json_data.getString("name");
                        String place=json_data.getString("email");
                     
                        data=data+"\n"+std+"  "+place;
                        Log.i("log_tag",result);
                       
                }
        }
       
        catch(JSONException e)
        {
                Log.e("log_tag", "Error parsing data "+e.toString());
        }
        new AlertDialog.Builder(this).setPositiveButton("Ok",new OnClickListener() {

            //@Override
            public void onClick(DialogInterface dialog, int which)
            {

            }
    }).setMessage(data).setTitle("Student Details").create().show();
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Generate Result"
        android:layout_marginTop="40dp"
        android:layout_gravity="center"
       
        android:onClick="click"/>
</LinearLayout>

XML Parsing

AndroidXmlParsingActivity.class

package com.androidhive.xmlparsing;

import java.util.ArrayList;
import java.util.HashMap;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class AndroidXMLParsingActivity extends ListActivity {

          // All static variables
          static final String URL = "http://api.androidhive.info/pizza/?format=xml";
          // XML node keys
          static final String KEY_ITEM = "item"; // parent node
          static final String KEY_ID = "id";
          static final String KEY_NAME = "name";
          static final String KEY_COST = "cost";
          static final String KEY_DESC = "description";

          @Override
          public void onCreate(Bundle savedInstanceState) {
                   super.onCreate(savedInstanceState);
                   setContentView(R.layout.main);

                   ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();

                   XMLParser parser = new XMLParser();
                   String xml = parser.getXmlFromUrl(URL); // getting XML
                   Document doc = parser.getDomElement(xml); // getting DOM element

                   NodeList nl = doc.getElementsByTagName(KEY_ITEM);
                   // looping through all item nodes <item>
                   for (int i = 0; i < nl.getLength(); i++) {
                             // creating new HashMap
                             HashMap<String, String> map = new HashMap<String, String>();
                             Element e = (Element) nl.item(i);
                             // adding each child node to HashMap key => value
                             map.put(KEY_ID, parser.getValue(e, KEY_ID));
                             map.put(KEY_NAME, parser.getValue(e, KEY_NAME));
                             map.put(KEY_COST, "Rs." + parser.getValue(e, KEY_COST));
                             map.put(KEY_DESC, parser.getValue(e, KEY_DESC));

                             // adding HashList to ArrayList
                             menuItems.add(map);
                   }

                   // Adding menuItems to ListView
                   ListAdapter adapter = new SimpleAdapter(this, menuItems,
                                      R.layout.list_item,
                                      new String[] { KEY_NAME, KEY_DESC, KEY_COST }, new int[] {
                                                          R.id.name, R.id.desciption, R.id.cost });

                   setListAdapter(adapter);

                   // selecting single ListView item
                   ListView lv = getListView();

                   lv.setOnItemClickListener(new OnItemClickListener() {

                             @Override
                             public void onItemClick(AdapterView<?> parent, View view,
                                                int position, long id) {
                                      // getting values from selected ListItem
                                      String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
                                      String cost = ((TextView) view.findViewById(R.id.cost)).getText().toString();
                                      String description = ((TextView) view.findViewById(R.id.desciption)).getText().toString();
                                     
                                      // Starting new intent
                                      Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
                                      in.putExtra(KEY_NAME, name);
                                      in.putExtra(KEY_COST, cost);
                                      in.putExtra(KEY_DESC, description);
                                      startActivity(in);

                             }
                   });
          }
}

XMLParser.class

package com.androidhive.xmlparsing;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;

public class XMLParser {

          // constructor
          public XMLParser() {

          }

          /**
           * Getting XML from URL making HTTP request
           * @param url string
           * */
          public String getXmlFromUrl(String url) {
                   String xml = null;

                   try {
                             // defaultHttpClient
                             DefaultHttpClient httpClient = new DefaultHttpClient();
                             HttpPost httpPost = new HttpPost(url);

                             HttpResponse httpResponse = httpClient.execute(httpPost);
                             HttpEntity httpEntity = httpResponse.getEntity();
                             xml = EntityUtils.toString(httpEntity);

                   } catch (UnsupportedEncodingException e) {
                             e.printStackTrace();
                   } catch (ClientProtocolException e) {
                             e.printStackTrace();
                   } catch (IOException e) {
                             e.printStackTrace();
                   }
                   // return XML
                   return xml;
          }
         
          /**
           * Getting XML DOM element
           * @param XML string
           * */
          public Document getDomElement(String xml){
                   Document doc = null;
                   DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                   try {

                             DocumentBuilder db = dbf.newDocumentBuilder();

                             InputSource is = new InputSource();
                           is.setCharacterStream(new StringReader(xml));
                           doc = db.parse(is);

                             } catch (ParserConfigurationException e) {
                                      Log.e("Error: ", e.getMessage());
                                      return null;
                             } catch (SAXException e) {
                                      Log.e("Error: ", e.getMessage());
                      return null;
                             } catch (IOException e) {
                                      Log.e("Error: ", e.getMessage());
                                      return null;
                             }

                  return doc;
          }
         
          /** Getting node value
            * @param elem element
            */
           public final String getElementValue( Node elem ) {
               Node child;
               if( elem != null){
                   if (elem.hasChildNodes()){
                       for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
                           if( child.getNodeType() == Node.TEXT_NODE  ){
                               return child.getNodeValue();
                           }
                       }
                   }
               }
               return "";
           }
           
           /**
            * Getting node value
            * @param Element node
            * @param key string
            * */
           public String getValue(Element item, String str) {           
                             NodeList n = item.getElementsByTagName(str);              
                             return this.getElementValue(n.item(0));
                   }
}

SingleMenuItemActivity.class

package com.androidhive.xmlparsing;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class SingleMenuItemActivity  extends Activity {
         
          // XML node keys
          static final String KEY_NAME = "name";
          static final String KEY_COST = "cost";
          static final String KEY_DESC = "description";
          @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.single_list_item);
       
        // getting intent data
        Intent in = getIntent();
       
        // Get XML values from previous intent
        String name = in.getStringExtra(KEY_NAME);
        String cost = in.getStringExtra(KEY_COST);
        String description = in.getStringExtra(KEY_DESC);
       
        // Displaying all values on the screen
        TextView lblName = (TextView) findViewById(R.id.name_label);
        TextView lblCost = (TextView) findViewById(R.id.cost_label);
        TextView lblDesc = (TextView) findViewById(R.id.description_label);
        
        lblName.setText(name);
        lblCost.setText(cost);
        lblDesc.setText(description);
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
          <!-- Main ListView
                    Always give id value as list(@android:id/list)
          -->
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"> 
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
                   <!-- Name Label -->
        <TextView
            android:id="@+id/name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#dc6800"
            android:textSize="16sp"
            android:textStyle="bold"
            android:paddingTop="6dip"
            android:paddingBottom="2dip" />
                   <!-- Description label -->
        <TextView
            android:id="@+id/desciption"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#acacac"
            android:paddingBottom="2dip">
        </TextView>
        <!-- Linear layout for cost and price Cost: Rs.100 -->
        <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <!-- Cost Label -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#5d5d5d"
            android:gravity="left"
            android:textStyle="bold"
            android:text="Cost: " >
        </TextView>
        <!-- Price Label -->
        <TextView
            android:id="@+id/cost"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#acacac"
            android:textStyle="bold"
            android:gravity="left">
        </TextView>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

single_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <!-- Name Label -->
  <TextView android:id="@+id/name_label"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="25dip"
            android:textStyle="bold"
            android:paddingTop="10dip"
            android:paddingBottom="10dip"
            android:textColor="#dc6800"/>
  <!-- Description Label -->
  <TextView android:id="@+id/description_label"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#acacac"/>
  <!-- Price Label -->
  <TextView android:id="@+id/cost_label"
                   android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:textStyle="bold"/>
</LinearLayout>