使用BroadcastReceiver的Android IntentService
在本教程中,我们将讨论Android框架的基本组件之一,即IntentService。
我们将使用BroadcastReceiver开发一个Android IntentService应用程序。
Android IntentService
我们在之前的教程中讨论了Android服务。
IntentService扩展了Service类。
Services和IntentServices均用于运行不需要UI的操作。
IntentService用于顺序运行数据。
每次您对服务调用Intent时,该操作都会添加到队列中。
Android IntentService与服务
使用startService()调用服务 | 使用Intent调用IntentService |
---|---|
服务可以从任何线程调用。 | IntentService只能从主线程调用 |
默认情况下,服务在应用程序的主线程上运行后台操作。因此,它会阻塞应用程序的UI。 | IntentService会创建一个单独的工作线程来运行后台操作 |
多次调用的服务将创建多个实例。 | 多次调用的IntentService不会创建多个实例 |
需要使用stopSelf()或stopService()停止服务 | IntentService在队列完成后自动停止。无需触发stopService()或stopSelf() |
Android服务可以运行并行操作。 | 在IntentService中,多个intent调用会自动排队并执行顺序。一个IntentService不能像服务一样运行并行操作 |
在服务中,当从活动传递意图时,将调用onHandleIntent()方法。
BroadcastReceivers用于在应用程序之间或者服务与活动之间传输消息。
为了在服务和活动之间传输数据,我们需要使用LocalBroadcastManager。
支持库随附LocalBroadcastManager类,该类仅用于本地传输数据。
您无法在应用程序外部传输数据。
在下一节中,我们将创建一个应用程序,该应用程序将字符串传递给IntentService,并在延迟后将其返回给Activity。
多亏了IntentService,这是顺序发生的。
Android IntentService示例项目结构
布局代码
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <EditText android:id="@+id/inputText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="8dp" android:hint="Enter your message" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="Send Message" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/inputText" <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="24dp" android:text="Message received from the Service is:\n" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" </android.support.constraint.ConstraintLayout>
MainActivity.java类的代码如下:
package com.theitroad.androidintentservices; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends AppCompatActivity { TextView textView; Button button; EditText editText; MyReceiver myReceiver; public static final String FILTER_ACTION_KEY = "any_key"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.textView); button = findViewById(R.id.button); editText = findViewById(R.id.inputText); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String message = editText.getText().toString(); Intent intent = new Intent(MainActivity.this, MyService.class); intent.putExtra("message", message); startService(intent); } }); } private void setReceiver() { myReceiver = new MyReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(FILTER_ACTION_KEY); LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, intentFilter); } @Override protected void onStart() { setReceiver(); super.onStart(); } @Override protected void onStop() { unregisterReceiver(myReceiver); super.onStop(); } private class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String message = intent.getStringExtra("broadcastMessage"); textView.setText(textView.getText() + "\n" + message); } } }
一些要点:
我们需要设置一个IntentFilter来注册我们的BroadcastReceiver。
在IntentFilter Action中,我们指定一个字符串。
同样的字符串也将在我们的IntentService中使用。
我们必须使用onStop()方法注销我们的BroadcastReceiver。
LocalBroadcastManager实例用于设置接收者。
我们的BroadcastReceiver将附加从服务返回的字符串。
MyService.java类的代码如下:
package com.theitroad.androidintentservices; import android.app.IntentService; import android.content.Intent; import android.os.SystemClock; import android.support.v4.content.LocalBroadcastManager; public class MyService extends IntentService { public MyService() { super("MyService"); } @Override protected void onHandleIntent(Intent intent) { String message = intent.getStringExtra("message"); intent.setAction(MainActivity.FILTER_ACTION_KEY); SystemClock.sleep(3000); String echoMessage = "IntentService after a pause of 3 seconds echoes " + message; LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent.putExtra("broadcastMessage", echoMessage)); } }
要将数据返回到活动,我们使用sendBroadcast方法。
它将数据传递到BroadcastReceiver。
广播接收器最终将数据传递给活动。
您必须在列表文件中声明服务。
如果没有LocalBroadcastManager,则不会传递上述数据。