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 used
Runnable
Interface implementation to define threadsClass MyThread implemments Runnable {@override public void run() {Copy the code
- use
Runnable
Interface to start a threadMyThread 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
- Message
- Messages passed between processes can carry a small amount of information internally for the exchange of data between different threads
- Handler
- Used to send and process messages
sendMessage()
handleMessage()
- MessageQueue
- Used to hold all messages sent through Handler
- There is always a message queue waiting to be processed
- Only one per thread
- Looper
- MessageQueue manager, infinite loop, whenever found in MessageQueue messages will be taken out and passed to
handleMessage()
- Only one per thread
- MessageQueue manager, infinite loop, whenever found in MessageQueue messages will be taken out and passed to
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 tasksProgress
: 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
onPreExecute()
- Called before background task starts
- Used to initialize the interface
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 needed
publishProgress(Progress...)
To complete the
onProgressUpdate(Progress...)
- When called in background task
publishProgress(Progress...)
After the call - The parameters carried are passed in the background task
- You can do UI operations
- When called in background task
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