The first line of code reading notes

service

  • Android implementation background running solutions
  • Tasks that do not require user interaction and require long running
  • Depends on the application process in which the service was created
  • Actively create child threads within the service to prevent the main thread from being blocked

Multithreaded programming

Basic usage

  • Define the thread
    Class MyThread extends Thread {@override public void run() {}Copy the code
  • Starting a thread
    new MyThread().start();
    Copy the code
  • Use inheritance for high coupling, commonly usedRunnableInterface implementation to define threads
    Class MyThread implemments Runnable {@override public void run() {Copy the code
  • useRunnableInterface to start a thread
    MyThread myThread = new MyThread();
    new Thread(myThread).start();
    Copy the code
  • Anonymous class implementations are more common
    New Thread(new Runnable() {@override public void run() {Copy the code

Update the UI in the child thread

  • Asynchronous message processing
public class MainActivity extends AppCompatActivity implements View.OnClickListener { public static final int UPDATE_TEXT = 1; private TextView text; private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case UPDATE_TEXT: Text. SetText ("Nice to meet you"); break; default: break; }}}... @Override public void onClick(View v) { switch (v.getId()) { case R.id.change_text: new Thread(new Runnable() { @Override public void run() { Message message = new Message(); message.what = UPDATE_TEXT; handler.sendMessage(message); }})}}}Copy the code

Resolve the asynchronous message processing mechanism

  1. Message
    • Messages passed between processes can carry a small amount of information internally for the exchange of data between different threads
  2. Handler
    • Used to send and process messages
    • sendMessage() handleMessage()
  3. MessageQueue
    • Used to hold all messages sent through Handler
    • There is always a message queue waiting to be processed
    • Only one per thread
  4. Looper
    • MessageQueue manager, infinite loop, whenever found in MessageQueue messages will be taken out and passed tohandleMessage()
    • Only one per thread
  • runOnUiThread(): interface encapsulation for asynchronous message processing

Using AsyncTask

  • Abstract class, which can be inherited by specifying three generic parameters
    • Params: Parameter to be passed in when AsyncTask is executed. It can be used in background tasks
    • Progress: Progress unit (During background task execution, if the current progress needs to be displayed on the interface)
    • Result: Return value type (when the task is finished, if the result needs to be returned)
  • Methods that often need to be overridden
    1. onPreExecute()
      • Called before background task starts
      • Used to initialize the interface
    2. doInBackground(Params...)
      • Handle all time-consuming tasks
      • After completing the task, you can use return to return the task execution result
      • If the third generic parameter of AsynTask is Void, the result of the task is not returned
      • Cannot perform UI operations, call if neededpublishProgress(Progress...)To complete the
    3. onProgressUpdate(Progress...)
      • When called in background taskpublishProgress(Progress...)After the call
      • The parameters carried are passed in the background task
      • You can do UI operations
    4. onPostExecute(Result)
      • Called when a background task is completed and is returned by a return statement
      • Returns data as a parameter
      • You can do UI operations
  • E.g.
    class DownloadTask extends AsyncTask<Void, Integer, Boolean> { @Override protected void onPreExecute() { ProgressDialog.show(); } @Override protected Boolean doInBackground(Void... params) { try { while (true) { int downloadPercent = doDownload(); publishProgress(downloadPercent); if (downloadPercent >= 100) { break; } } } catch (Exception e) { return false; } return true; } @Override protected void onProgressUpdate(Integer... values) { progressDialog.setMessage("Download " + values[0] + "%"); } @Override protected void onPostExecute(Boolean result) { progressDialog.dismiss(); if (result) { Toast.makeText(context, "Download succeeded", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, ""Download failed", Toast.LENGTH_SHORT).show(); }}}Copy the code
  • Start the task

    new DownloadTask().execute()

Basic usage of the service

Defining a service

  • New->Service->Service
    • Exported: Whether to run an application other than the current one to access the service
    • Enabled: Whether to enable the service
public class Myservice extends Service() {
    public MyService() {
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }
    
    @Override
    public void onCreate() {
        super.onCreate();
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommond(intent, flags, startId);
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}
Copy the code
  • OnStartCommand () : executes as soon as the service starts
<service
    android:name=".MyService"
    android:enabled="true"
    android:exported="true">
</service>
Copy the code

Start and stop services

@Override public void onClick(View v) { switch (v.getId()) { case R.id.start_service: Intent startIntent new Intent(this, MyService.class); startService(startIntent); break; case R.id.stop_service: Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); break; default: break; }}Copy the code

Activities and services are communicated

  • onBind()

  • MyService:

    public class MyService extends Service { private DownloadBinder mBinder = new DownloadBinder(); class DownloadBinder extends Binder { public void startDownload() { Log.d("MyService", "startDownload executed"); } public int getProgress() { Log.d("MyService", "getProgress executed"); return 0; } } @Override public IBinder onBind(Intent intent) { return mBinder; }}Copy the code
  • In the MainActivity

    private MyService.DownloadBinder downloadBinder; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { downloadBinder = (MyService.DownloadBinder) service; downloadBinder.startDownload(); downloadBinder.getProgress(); }}Copy the code
    @Override public void onClick(View v) { switch (v.getId()) { ... case R.id.bind_service: Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, BIND_AUTOCEATE); break; case R.id.unbind_service: unbindService(connection); break; default: break; }}Copy the code

Life cycle of the service

  • OnCreate () (if the activity is not created) -> onStartCommand() -> Run until StopService() or stopSelf() is called
  • Call Contextd bindService to get a persistent link to a service
  • OnDestroy () can only be executed when stopService() and unbindService() are called simultaneously

Other skills

The front desk service

  • Prevent you from being reclaimed due to insufficient system memory
  • There is always a running icon in the status bar of the system
  • MyService onCreate() :
    Intent intent = new Intent(this, MainActivity.class);
    PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
    Notification notification = new NotificationCompat.Builder(this)
            .setContentTitle("This is content title")
            .setContentText("This is content text")
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.mipmap.ic_launcher)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
            .setContentIntent(pi)
            .build();
    startForeground(1, notification);
    Copy the code

IntentService

public MyIntentService extentds IntentService { public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { Log.d("MyIntentService", "Thread id is " + Thread.currentThread().getId()); } @Override public void onDestroy() { super.onDestroy(); Log.d("MyIntentService", "onDestroy executed"); }}Copy the code