Android application package using ANT

Android application package using ANT

Hello everyone, today to share with you how to use ANT Android application package.
Usually we used to use eclipse to develop Android program, it will automatically help us pack the current application. If the Navigator view, we can see the following files:



In the figure above, com package is placed in our class file, classes.dex a class file after the conversion can be run on the dalvik streamline class file, resources.ap_ is through packaged resource file, ant.apk is The final package file.
ANT to use the application package, usually through the following steps:
1. aapt command generates R.java file
2. generate the corresponding java file with the command aidl
3. Use the javac command to compile the java source files to generate class files
4. dx.bat converts class files into classes.dex file
5. Generate resource package file with the command resources.ap_ aapt
6. apkbuilder.bat packaging resources and classes.dex files, generate unsigned.apk
7. jarsinger command apk certification, generate signed.apk
In order to facilitate understanding and memory, here to a flowchart to illustrate the above processes:



Above is the whole process, here we were made to explain in detail each of its parts, to figure out each step.
We need to familiarize yourself with each step using the command:
1.aapt (Android Asset Packaging Tool) command to generate R.java file based resource file


Parameter Description:
-f Force overwrite the existing file.
-m automatically generate the appropriate package directory at the location specified -J.
-J Specifies R.java file generated directory.
-S Specifies the resource directory.
-M Specify the manifest file.
-I Introduced libraries.
Note that the location where the ant our current project root directory, so many paths to enter, if necessary, on command, the following example is the same.
2.aidl (Android Interface Definition Language) commands to generate java files based .aidl definition file

The above examples of the location for the next com / scott / ant, according to package Person.aidl files generated gen Person.java corresponding directory file, example only handle a single document, the following will describe how to handle directory multiple aidl files.
3.javac (Java Compiler) command to generate a corresponding class file based on the source file


Parameter Description:
Location -d <directory> specify where the generated class file
-bootclasspath <path> Override location of bootstrap class files
Example and not take into account the following libraries referenced class path, complex cases will later encounter.
4.dx command to convert the file into a class file .dex



The above example is to convert the class file into the bin directory classes.dex file, the output to the bin directory, we may use third-party libraries, you will see later on.
The resource file is packaged 5.aapt



Parameter Description:
-f mandatory coverage
-M Specify the Manifest file
-S Specifies the resource directory
-A Specifies Inventory
-I Redistribute library
-F Specifies the package to be generated
6.apkbuilder order, according to documents and resources.ap_ classes.dex generated as visa apk package



Parameter Description:
-rf reference directory structure of the source file
7.jarsigner command to generate above apk package visa


In the process of visa, the need to use the certificate file needs to be noted that the final release is an alias for the certificate, on how to create a certificate, see below:

Of course, the above steps can also be done using ADT provides a graphical interface in eclipse, the selected item, right-click, "Android Tools => Export Signed Application Package", then select one of the Keystore selection link "Create new keystore", then follow the prompts Fill in the information on it.
These are the commands we used to, then we ought to analyze the necessary ANT build.xml:
First we need to define a large number of variable attributes, used to indicate the use of the path, directories, etc., as follows:





Then, we carried out step by step, first, initialization:



Second is to generate R.java file:



Followed aidl generate java source files:



We specify a framework.aidl, which defines a lot of android built-in objects, then we specify aidl directory and output directory, compiled after the group designated as aidl file suffix.
Next is the source file is compiled into class files:



If you use the third-party libraries, we can configure the classpath tag.
Next it is to convert class files into classes.dex:



Like the above code, if the use of third-party libraries, can be added in the form of final arguments into account.
Then the resource file is packaged:



No visa is then packaged into the apk package:



Then is apk visa:



Last post:



This completes the editing build.xml, eclipse inherited the ANT, so we can run directly in the eclipse can also call in your code.
First we need to download ANT, then configure the environment variable information, and finally we called with:





Detailes using Android with AsyncTask Part2

Detailes using Android with AsyncTask Part2

You can see onCancelled () method will be called, onPostExecute (Result result) method will not be called.
The above describes the basic application AsyncTask, some friends may have doubts, AsyncTask internally how to perform it, process it performs what is the difference between using the Handler with us? The answer is: AsyncTask Thread + Handler is a good package, android.os.AsyncTask code can still see traces of Thread and Handler. Here to tell you in detail about the implementation of the principle of AsyncTask.
We look at the outline view AsyncTask:

We can see that the methods are crucial steps in which, doInBackground (Params ... params) is an abstract method, you must overwrite this method we have inherited AsyncTask; onPreExecute (), onProgressUpdate (Progress ... values), onPostExecute (Result result), onCancelled () method body these are empty, when we need to be able to selectively overwrite them; publishProgress (Progress ... values) is the final modification can not be overwritten only to call, we usually call doInBackground (Params ... params) in this method; in addition, we can see a Status enum class and getStatus () method, Status enum class code section as follows:

      // Initial state 
    Private  volatile  Status mStatus = Status.PENDING; 
     
    public  enum  Status { 
        
         * Indicates that the task has not been executed yet.
          
        PENDING, 
        
         * Indicates that the task is running.
          
        RUNNING, 
        
         * Indicates that {link AsyncTask # onPostExecute} has finished.
          
        FINISHED, 
     

     * Returns the current status of this task.
     
     *return The current status.
      
    public  Final  Status getStatus () { 
        return  mStatus; 


You can see that the initial state AsyncTask is PENDING, on behalf of a pending state, RUNNING representatives execution state, FINISHED on behalf of the end state, several states in a life cycle AsyncTask be used in many places, it is very important.
After the introduction to the outline view relevant content, then, we will from execute (Params ... params) as the entrance, the focus of analysis of the implementation process AsyncTask, we look at the code snippet execute (Params ... params) method:
     

public  Final  AsyncTask <Params, Progress, Result> execute (Params ... params) { 
        if  (mStatus! = Status.PENDING) { 
            switch  (mStatus) { 
                Case  RUNNING: 
                    // If the task is being executed is thrown 
                    // It is worth mentioning that after the call cancel canceled task, the state has not public  Final  AsyncTask <Params, Progress, Result> execute (Params ... params) { 
        if  (mStatus! = Status.PENDING) { 
            switch  (mStatus) { 
                Case  RUNNING: 
                    // If the task is being executed is thrown 
                    // It is worth mentioning that after the call cancel canceled task, the state has not yet RUNNING 
                    throw  new  IllegalStateException ( "Can not execute Task:" 
                            +  "the Task is already running." ); 
                Case  FINISHED: 
                    // If the task has finished executing exception is thrown 
                    throw  new  IllegalStateException ( "Can not execute Task:" 
                            +  "the Task has already Been Executed" 
                            +  "(a Task CAN be Executed only once)" ); 
             
         
         
        // Change status is RUNNING 
        mStatus = Status.RUNNING; 
        // Method call onPreExecute 
        onPreExecute (); 
        mWorker.mParams = params; 
        sExecutor.execute (mFuture); 
        return  this ;       


Code involves three strange variables: mWorker, sExecutor, mFuture, we will look at their true colors:
About sExecutor, it is an instance of java.util.concurrent.ThreadPoolExecutor for executive management of the thread. Code is as follows:
     
Private  static  Final  int  CORE_POOL_SIZE =  5 ; 
   Private  static  Final  int  MAXIMUM_POOL_SIZE =  128 ; 
   Private  static  Final  int  KEEP_ALIVE =  10 ; 
// Create a queue for storing threads 
   Private  static  Final  BlockingQueue <Runnable> sWorkQueue = 
           new  LinkedBlockingQueue <Runnable> ( 10 ); 
// Create a thread factory 
   Private  static  Final  ThreadFactory sThreadFactory =  new  ThreadFactory () { 
       Private  Final  AtomicInteger mCount =  new  AtomicInteger ( 1 ); 
    // Create a new thread 
       public  Thread newthread (Runnable r) { 
           return  new  Thread (r,  "AsyncTask #"  + mCount.getAndIncrement ()); 
        
    
// Create a thread pool actuator for performing management thread 
   Private  static  Final  ThreadPoolExecutor sExecutor =  new  ThreadPoolExecutor (CORE_POOL_SIZE, 
           MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory); 


mWorker actually implement an abstract object instance inner class AsyncTask, which implements Callable <Result> interface call () method, as follows:

Private  static  abstract  class  WorkerRunnable <Params, Result>  implements  Callable <Result> { 
        Params [] mParams;


And mFuture actually an instance java.util.concurrent.FutureTask, the following information is relevant to its FutureTask class:


public  class  FutureTask <V>  implements  RunnableFuture <V> { 


public  interface  RunnableFuture <V>  extends  Runnable, Future <V> { 
    
     * Sets this Future to the result of its computation
     * Unless it has been cancelled.
      
    void  run (); 

You can see the class FutureTask is canceled midway for an asynchronous computation.
The following are examples of mWorker and mFuture reflected in AsyncTask in:

Private  Final  WorkerRunnable <Params, Result> mWorker; 
   Private  Final  FutureTask <Result> mFuture; 
public  AsyncTask () { 
       mWorker =  new  WorkerRunnable <Params, Result> () { 
           After // call method is called, it will set priorities for the background level, and then call the method AsyncTask of doInBackground 
        public  Result Call ()  throws  Exception { 
               Process.setThreadPriority (Process.THREAD_PRIORITY_BACKGROUND); 
               return  doInBackground (mParams); 
             
        
    // In mFuture instance, will call mWorker do background tasks, method calls done after the completion of 
       mFuture =  new  FutureTask <Result> (mWorker) { 
           Override 
           protected  void  DONE () { 
               Message message; 
               Result result =  null ; 
               try  { 
                   result = get (); 
               }  catch  (InterruptedException e) { 
                   android.util.Log.w (LOG_TAG, e); 
               }  catch  (ExecutionException e) { 
                   throw  new  RuntimeException ( "An error occured while executing doInBackground ()" , 
                           e.getCause ()); 
               }  catch  (CancellationException e) { 
                // Send the message to cancel the task 
                   message = sHandler.obtainMessage (MESSAGE_POST_CANCEL, 
                           new  AsyncTaskResult <Result> (AsyncTask. this , (Result [])  null )); 
                   message.sendToTarget (); 
                   return ; 
               }  catch  (Throwable t) { 
                   throw  new  RuntimeException ( "An error occured while executing" 
                           +  "doInBackground ()" , t); 
                
            // Display the results send a message 
               message = sHandler.obtainMessage (MESSAGE_POST_RESULT, 
                       new  AsyncTaskResult <Result> (AsyncTask. this , result)); 
               message.sendToTarget (); 
            
        
    

We see the above code, done mFuture object instance () method, if captured CancellationException type of anomaly, it sends a "MESSAGE_POST_CANCEL" message; if successfully implemented, it sends a "MESSAGE_POST_RESULT" message, and the message sHandler is associated with an object. This is actually an instance AsyncTask sHandler instance inner class InternalHandler, and it is inherited InternalHandler Handler, let's analyze its code:

Private  void  Finish (Result result) { 
        if  (isCancelled ()) result =  null ; 
        onPostExecute (result);   // display the results call onPostExecute 
        mStatus = Status.FINISHED;   // change status is FINISHED 

The original finish () method is responsible for calling onPostExecute (Result result) method to display the results and change task status ah.
In addition, done mFuture object () method to construct a message, the message contains a AsyncTaskResult type of object, and then handleMessage sHandler instances of an object (Message msg) method, the use of the following in this way obtain information that came Object:

AsyncTaskResult result = (AsyncTaskResult) msg.obj;

What exactly is this AsyncTaskResult it, what does it contain? In fact, it is an internal class AsyncTask, is used to wrap a class execution results, let us look at its structure:

// Send the message to cancel the task 
message = sHandler.obtainMessage (MESSAGE_POST_CANCEL, 
        new  AsyncTaskResult <Result> (AsyncTask. this , (Result [])  null )); 
message.sendToTarget (); 

// Display the results send a message 
message = sHandler.obtainMessage (MESSAGE_POST_RESULT, 
         new  AsyncTaskResult <Result> (AsyncTask. this , result)); 
message.sendToTarget (); 


In dealing with the message of how to use this object, let's look again:

result.mTask.finish (result.mData [ 0 ]);

result.mTask.onProgressUpdate (result.mData); 

Generally speaking, when we call the execute (Params ... params) method, execute method calls onPreExecute () method, and then perform a task by the ThreadPoolExecutor instance FutureTask sExecutor, this process doInBackground (Params ... params) will be calls, if the developer overwritten doInBackground (Params ... params) method calls publishProgress (Progress ... values) method, by InternalHandler instance sHandler send a MESSAGE_POST_PROGRESS message, update schedule, when sHandler processing messages onProgressUpdate ( Progress ... values) method is called; if you encounter an exception, it sends a message MESSAGE_POST_CANCEL, cancel the task, onCancelled () method will be called when sHandler processing the message; If successful, it sends a message MESSAGE_POST_RESULT display Results, onPostExecute (Result result) method is called when sHandler process the message.
After the above description, I believe that friends have recognized the nature of the AsyncTask, it Thread + Handler good package, reducing the complexity of the developers deal with the problem, improve the efficiency of development, I hope you can a lot of taste.

Detailes using Android with AsyncTask Part1

Detailes using Android with AsyncTask

Asynchronous task mechanism in Android, there are two ways, Handler and AsyncTask.
Handler mode for each task you need to create a new thread, Handler instance by sending a message to the UI thread, complete interface update task is completed, this way to control the entire process is relatively fine, but there are also disadvantages, such as code opposite bloated, perform multiple tasks at the same time, easy to thread precise control. Handler relevant knowledge on the front has also been introduced, it is unclear friends can refer to it.
To simplify operation, Android1.5 provides tools android.os.AsyncTask, it makes it easier to create asynchronous tasks, no longer need to write task threads and Handler instances to accomplish the same task.
Let's look at the definition AsyncTask of:


public  abstract  class  AsyncTask <Params, Progress, Result> {

Three generic type representing the "input parameter to start the task execution" and "background task execution schedule", "backstage calculation type." In certain cases, not all types are used, if not used, can be replaced with java.lang.Void type.
A perform asynchronous tasks typically include the following steps:
1. execute (Params ... params) , perform an asynchronous task, we need to call this method in your code, trigger the execution of asynchronous tasks.
2. onPreExecute () , immediately after the execute (Params ... params) is called, is generally used to perform background tasks before the UI to make some marks.
3. doInBackground (Params ... params) , in onPreExecute () immediately after the completion of the implementation, for the implementation of a more time-consuming operation, this method will receive input parameters and returns the results. In the process of implementation can call publishProgress (Progress ... values) to update the progress information.
4. onProgressUpdate (Progress ... values) , when calling publishProgress (Progress ... values), this method is executed, it will update the progress information directly to the UI components.
5. onPostExecute (Result result) , when the end of a background operation, this method will be called, the results will be passed as an argument to this method, the direct result is displayed on the UI components.
When in use, there are a few things to pay particular attention to:
Examples 1. asynchronous tasks must be created in the UI thread.
2.execute (Params ... params) method must be called on the UI thread.
3. Do not manually call onPreExecute (), doInBackground (Params ... params), onProgressUpdate (Progress ... values), onPostExecute (Result result) these methods.
4. You can not change the information UI components doInBackground (Params ... params) in.
5. A task instance can only be executed once, if you perform a second time will throw an exception.
Next, we look at how to use AsyncTask perform asynchronous task operation, we first create a project structure is as follows:



The structure is relatively simple, let's look at MainActivity.java code:

Package  com.scott.async; 
Import  java.io.ByteArrayOutputStream; 
Import  java.io.InputStream; 
Import  org.apache.http.HttpEntity; 
Import  org.apache.http.HttpResponse; 
Import  org.apache.http.HttpStatus; 
Import  org.apache.http.client.HttpClient; 
Import  org.apache.http.client.methods.HttpGet; 
Import  org.apache.http.impl.client.DefaultHttpClient; 
Import  android.app.Activity; 
Import  android.os.AsyncTask; 
Import  android.os.Bundle; 
Import  android.util.Log; 
Import  android.view.View; 
Import  android.widget.Button; 
Import  android.widget.ProgressBar; 
Import  android.widget.TextView; 
public  class  MainActivity  extends  Activity { 
     
    Private  static  Final  String TAG =  "ASYNC_TASK" ; 
     
    Private  Button execute; 
    Private  Button Cancel; 
    Private  ProgressBar progressBar; 
    Private  TextView textView; 
     
    Private  MyTask mTask; 
     
    Override 
    public  void  onCreate (Bundle savedInstanceState) { 
        Super .onCreate (savedInstanceState); 
        setContentView (R.layout.main); 
         
        execute = (Button) findViewById (R.id.execute); 
        execute.setOnClickListener ( new  View.OnClickListener () { 
            Override 
            public  void  onClick (View v) { 
                // Note that each required a new instance, the new task can only be executed once, there would be an exception 
                mTask =  new  MyTask (); 
                mTask.execute ( "http://www.androidx7.com" ); 
                 
                execute.setEnabled ( false );              
                cancel.setEnabled ( true ); 
          
        cancel = (Button) findViewById (R.id.cancel); 
        cancel.setOnClickListener ( new  View.OnClickListener () { 
            Override 
            public  void  onClick (View v) { 
                // Cancel the task being executed, onCancelled method will be called 
                mTask.cancel ( true ); 
      

        progressBar = (ProgressBar) findViewById (R.id.progress_bar); 
        textView = (TextView) findViewById (R.id.text_view); 
         
     
     
    Private  class  MyTask  extends  AsyncTask <String, Integer, String> { 
        // OnPreExecute method for performing background tasks before doing some UI operations 
        Override 
        protected  void  onPreExecute () { 
            Log.i (TAG,  "onPreExecute () Called" ); 
            textView.setText ( "loading ..." ); 
       
         
        Internal // doInBackground method to perform background tasks can not be modified in this method UI 
        Override 
        protected  String doInBackground (String ... params) { 
            Log.i (TAG,  "doInBackground (Params ... params) Called" );  
            try  { 
                HttpClient Client =  new  DefaultHttpClient (); 
                HttpGet get =  new  HttpGet (params [ 0 ]); 
                HttpResponse response = client.execute (get); 
                if  (response.getStatusLine (). getStatusCode () == HttpStatus.SC_OK) { 
                    HttpEntity entity = response.getEntity (); 
                    InputStream is = entity.getContent (); 
                    Long  Total = entity.getContentLength (); 
                    ByteArrayOutputStream Baos =  new  ByteArrayOutputStream (); 
                    byte [] buf =  new  byte [ 1024 ]; 
                    int  count =  0 ; 
                    int  length = - 1 ; 
                    while  ((length = is.read (buf)) = -! 1 ) { 
                        baos.write (buf,  0 , length); 
                        count + = length; 
                        // Call publishProgress schedule announced last onProgressUpdate   method will be executed 
                        publishProgress (( int ) ((count / ( float ) Total) *  100 )); 
                        // To demonstrate progress, sleep 500 milliseconds 
                        Thread.sleep ( 500 ); 

                    return  new  String (baos.toByteArray (),  "GB2312" ); 

            }  catch  (Exception e) { 
                Log.e (TAG, e.getMessage ()); 

            return  null ; 

        // OnProgressUpdate method for updating progress information 
        Override 
        protected  void  onProgressUpdate (Integer ... progresses) { 
            Log.i (TAG,  "onProgressUpdate (Progress ... progresses) Called" ); 
            ProgressBar.setProgress (progresses [ 0 ]); 
            textView.setText ( "loading ..."  + progresses [ 0 ] +  "%" ); 
        
         
        // OnPostExecute method is used in the station after the execution task updates UI, display the results 
        Override 
        protected  void  onPostExecute (String result) { 
            Log.i (TAG,  "onPostExecute (Result result) Called" ); 
            textView.setText (result); 
             
            execute.setEnabled ( true ); 
            cancel.setEnabled ( false ); 

         
        // OnCancelled method used to change the UI when you cancel the execution of the task 
        Override 
        protected  void  onCancelled () { 
            Log.i (TAG,  "onCancelled () Called" ); 
            textView.setText ( "canceled" ); 
            ProgressBar.setProgress ( 0 ); 
             
            execute.setEnabled ( true ); 
            cancel.setEnabled ( false ); 




Main.xml layout file code is as follows:

<? XML  Version = "1.0"  encoding = "UTF-8" ?> 
< LinearLayout  xmlns: Android = "http://schemas.android.com/apk/res/android" 
    Android: Orientation = "Vertical" 
    Android: layout_width = "fill_parent" 
    Android: layout_height = "fill_parent" > 
    < Button 
        Android: ID = "@ + ID / execute" 
        Android: layout_width = "fill_parent" 
        Android: layout_height = "wrap_content" 
        Android: text = "execute" /> 
    < Button 
        Android: ID = "@ + ID / Cancel" 
        Android: layout_width = "fill_parent" 
        Android: layout_height = "wrap_content" 
        Android: enabled = "false" 
        Android: text = "Cancel" /> 
    < ProgressBar  
        Android: ID = "@ + ID / progress_bar"  
        Android: layout_width = "fill_parent"  
        Android: layout_height = "wrap_content"  
        Android: Progress = "0" 
        Android: max = "100" 
        style = "Android:? attr / progressBarStyleHorizontal" /> 
    < ScrollView 
        Android: layout_width = "fill_parent"  
        Android: layout_height = "wrap_content" > 
        < TextView 
            Android: ID = "@ + ID / text_view" 
            Android: layout_width = "fill_parent"  
            Android: layout_height = "wrap_content" /> 
    </ ScrollView > 
</ LinearLayout > 


Because of the need to access the network, so we also need to add access to the network in AndroidManifest.xml permissions:

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


We look at the interface at runtime:






Several more shots were initial interface, the implementation of asynchronous task interface, the interface after successful execution, cancel the task after the interface. After the successful implementation of the whole process log is printed as follows:

If we press the "cancel" button in carrying out its mandate, the log is printed as follows: