Android Coding - hqzhang/cloudtestbed GitHub Wiki

octocat

Two types of JAVA Thread
1.	runnable  method
new Thread(new Runnable()
    {
        @Override
        public void run() {
            System.out.println("blah");
        }
    }).start();
2.	Thread method
new Thread()
    {
        public void run() {
            System.out.println("blah");
        }
    }.start();

octocat

V Android Thread vs Process

By default, all components of the same application run in the same process and most applications should not change this. However, if you find that you need to control which process a certain component belongs to, you can do so in the manifest file.
The manifest entry for each type of component element—<activity>, <service>, <receiver>, and<provider>—supports an android:process attribute that can specify a process in which that component should run.

•	Interprocess communication have to be the same app user ID
•	AIDL Example
AIDL technique is a light weighted client server architecture in form of a service,

1)	AIDL interface IMyService.aidl
interface IMyService {
    // WE can pass values along with in, out, or inout parameters. 
    // Android Java Primitive datatypes (such as int,, string, boolean, etc.) can only be passed in.
    int add(in int ValueFirst, in int valueSecond);
}

2)	Implement remote service  MyService.java
   public class MyService extends Service {
	public MyService() {
	}
	private IBinder mBinder = new LocalBinder();
	  @Override
	  public IBinder onBind(Intent intent) {
	  //TODO for communication return IBinder implementation
		  Toast.makeText(this, "onBind", Toast.LENGTH_LONG).show();
		 Log.i("", "Process Id in sumService"+android.os.Process.myPid());
	    return mBinder;
	  }
	////used for common service
    public int sum(int a, int b) {
    	Log.i("", "Process Id in sumService:"+android.os.Process.myPid());
        Toast.makeText(this, "Two num  was added in binder", Toast.LENGTH_LONG).show();
        return (a+b);
    }
   // public class LocalBinder extends Binder { //for service in main process
    public class LocalBinder extends IMyService.Stub { //for service in own proces
    	public MyService getService(){
    		Log.i("", "Process Id in sumService************"+android.os.Process.myPid());
    		return MyService.this;
    	}
		@Override
		public int add(int ValueFirst, int valueSecond) throws RemoteException {
			// TODO Auto-generated method stub
			return (ValueFirst+valueSecond);
		}
    	
    }
}

3)	Expose service to other local client.
public class MainActivity extends Activity {
	//UI
    EditText txt1;
    EditText txt2;
    EditText txt3;
    //Connection
    //MyService mService;//for common service
    IMyService mService;
    boolean mBound;
    ServiceConnection mConnection = new ServiceConnection(){

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
		      //mBound = true;
		     //LocalBinder binder = (LocalBinder)service;
		     //mService = binder.getService();//for common service
			mService = IMyService.Stub.asInterface((IBinder) service);
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			//mBound = false;
			mService = null;	
		}
    };
    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//UI
		txt1 = (EditText)findViewById(R.id.editText1);
		txt2 = (EditText)findViewById(R.id.editText2);
		txt3 = (EditText)findViewById(R.id.editText3);
		Intent in=new Intent(this,MyService.class);
		bindService(in, mConnection, BIND_AUTO_CREATE);
		
	}

	// Start the  service
	public void startNewService(View view) {
		System.out.println("enter AddService()************");
		Log.i("", "Process Id in AddService()************"+android.os.Process.myPid());
		int n1 = Integer.parseInt(txt1.getText().toString());
		int n2 = Integer.parseInt(txt2.getText().toString());
		int res = 0;
		 try {
			 Log.i("", "Process Id in MainProcess************"+android.os.Process.myPid());        
		     res = mService.add(n1, n2);
		   } catch (RemoteException e) {
		     Log.i("", "Data fetch failed with: " + e);
		     e.printStackTrace();
		   }
		 Log.i("", "Add result in MainProcess########:"+res); 
		   txt3.setText(new Integer(res).toString());

	}

	// Stop the  service
	public void stopNewService(View view) {
		stopService(new Intent(this, MyService.class));
	}
	
	@Override
	protected void onStart(){
		super.onStart();
		
	}
	@Override
	protected void onStop(){
		super.onStop();
		/*if(mBound){
			mService.unbindService(mConnection);
			mBound = false;
		}*/
		//////
		unbindService(mConnection);
		mConnection = null;
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
}

•	Mainthread Looper for Receiver, Activity, ==== messageQueue.
•	ThreadPool For ContentProvider and service ==== thread pools
1) Activity: runOnUiThread(runnable) in Ui Thread immediately
                           In other threads post to Uithread queue.
                           Seem like a post() or sendMsge()
2) View: post(runnable)   post mesge to mainthread looper
         postDelayed(runnable): run on Ui thread
3) Handler: post(runable)  : run on handler instance( not Uithread)
Process setThreadPriority
Handler instance is associate with a thread and thread messageQueue.
MsgQueue =Looper()==handleMsg() /sendMsg()
Two method to communicate with handler by thread’s Message Queue.,
Messages        
Runnable Objects
1) Get Message Objects POOL: Message.obtain() /Handler.obtainMessage()
2) sendMessage() /sendMessageDelayed()
   sendMessageAtFrontOfQueue()/sendMessageAtTime()
   sendEmptyMessage()
3) Handler:handleMessage() method

The difference between Hander.post() and View.post() is that Handler will run your code on the thread the Handler instance was created on (which is not necessarily the UI thread), while View will always run it on the UI thread (because views are bound to it).
  
1)Runnable just means piece of code.
  Interprocess data exchange by share Appuserid
 PackageManager packageManager=getPackageManager()      
 ApplicationInfo applicationInfo=packageManager.
 getApplicationInfo(“packagename”,PackageManager.GET_META_DATA)
   path= applicationInfo.dataDir
   ANR test: more that 60 second system appear “ANR”

2) Mainthread holds UI elementUpdate
                 System callback onKeyDown
                 Lifecycle callback onCreate()
                 Clickbutton drop a msg to it
                 Event for BCR invoke it on MT through mesge
3)Kill process when memory is low.
   
•	Multithread---------NOT GOOD

Void downloadImage()(view){
   Thread myThread = new Thread(new Mythread());
   myThread.start();
}

Class MyThread implements runnable{
Public void run(){
     Dosomething();
}
}

•	Handler   ---------RECOMMAND
Looper.prepare();
Hadler = New Handler();
Looper.looper()
•	AsyncTask ---------RECOMMAND
•	MainThread  ============   AsyncTask  ========== AsyncTask Status
1)	Execute(params)              ;           AsyncTask.Status.PENDING
2)	onPreExecute()== doInBackground(params)  AsyncTask.Status.RUNING    
3)	onProgressUpdate(pro)publishProgress(pro)AsyncTask.Status.RUNING
4)	onPostExecute(result)====return result;  AsyncTask.Status.FINISH
ThreeParms for AST
•	params ( input)
•	Progress
•	Result  (output)
5)	Mainthread for other activity/broadcastReceiver?? 
6)	ThreadPool for service/contentProvider
7)	Multithread
8)	Handler
9)	AsyncTask

I. Example of ImageDownload

I) general
   Thread myThread=new Thread(new downloadImagesThread());
   myThread.start();
   private class downloadImagesThread implements Runnable{
    	@Override
    	public void run(){
    		downloadIMageUsingThreads(listOfImages[1]);
    	}
   }

//anonymous
  Thread myThread=new Thread(new Runnable(){
         @Override
    	  public void run(){
    		downloadIMageUsingThreads(listOfImages[1]);
    	}

  }).start();
   

II. runUiThread vs Post option 1 vs option 2

handler=new Handler();
   Thread myThread=new Thread(new downloadImagesThread());
   myThread.start();    
   private class downloadImagesThread implements Runnable{
    	@Override
    	public void run(){
    		//option 1 using runOnUiThread(runnable)
    		/*AndroidGPSTrackingActivity.this.runOnUiThread(new Runnable(){
    			@Override
    			public void run(){
    				loadingSection.setVisibility(View.VISIBLE);
    			}
    		});*/
    		//option 2 using post runable();
    		handler.post(new Runnable() {
    			@Override
    			public void run(){
    				loadingSection.setVisibility(View.VISIBLE);
    			}
    		});
    		/*for(int i=0; i<10000;i++){
    			Message message=Message.obtain();
    			message.arg1=i;
    		    handler.sendMessage(message);
    		}*/
    		downloadIMageUsingThreads(listOfImages[1]);
    	}
    }

III. Progress Bar

  Thread myThread=new Thread(new downloadImagesThread());
  myThread.start();
  handler=new Handler(){
        	@Override
        	public void handleMessage(Message msg){
        		progressBar.setProgress(msg.arg1);
        		System.out.println("enter handleMessage()");
        	}
        };

private class downloadImagesThread implements Runnable{
    	@Override
    	public void run(){
    		for(int i=0; i<10000;i++){
    			total=total+read;
		Message message=Message.obtain();
    		message.arg1=total;
    		handler.sendMessage(message);
    		}	
    	}
    }

IV. Send Messge to background

    MyThread myThread =new MyThread();
    myThread.start();
    myThread.handler.post(new Runnable(){
    	   @Override
    	   public void run(){
    		   L.m(Thread.currentThread().getName());
    	   }
       });
  class MyThread extends Thread {
    	Handler handler;
    	@Override
    	public void run(){
    		Looper.prepare();
    		handler=new Handler();
    		Looper.loop();
    	}
    }

VI. AsyncTask: Progress bar.

MyTask myTask1 =new MyTask();
myTask1.execute(url);
                        
class MyTask extends AsyncTask<String,  // doInBackground(String... params)                           and  execute(url); 
                              Integer, //nProgressUpdate(Integer... values) 
                                        And publishProgress(Integer .. values)
                              Boolean>{// onPostExecute(Boolean result)
    	private int count=0;
    	ArrayAdapter<String> adapter;
    	@Override
    	protected void onPreExecute(){
    		L.m("I am in onPreExecute####################");
    		
    	}
    	@Override
	protected Boolean doInBackground(String... params) {
    		L.m("I am in doInBackground()####################");
			// TODO Auto-generated method stub
    		for(int item=0; item<100; item++){
    			publishProgress(item);
    			try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				}
    		}
			return true;
		}
    	protected void onProgressUpdate(Integer... values ){
    		L.m("I am in onProgressUpdate()####################");
    		
    		setProgress((int)((double) values[0]/texts.length)*10000);
    	}
    	protected void onPostExecute(Boolean result){
    		setProgressBarVisibility(false);
    		L.m("I am in onPostExecute()####################");
    		
    	}  
    	
    }
⚠️ **GitHub.com Fallback** ⚠️