android Intent各大厂家进入开启移动网络设置
转载
IntentService是继承并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统的Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们手动去控制或stopSelf()。另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。
使用了IntentService最起码有两个好处:
1. 一方面不需要自己去new Thread了;
2. 另一方面不需要考虑在什么时候关闭该Service了。
接下来让大家看一下实现的效果图:
这里写了一个耗时操作,每隔三秒请求一下数据
当请求数据的时候,会发送消息让后台service去处理,Service处理之后会返回给Activity , 然后Activity会更新UI
UploadImgService
继承自IntentService的实现类,会自动生成一个onHandlerIntent的方法
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class UploadImgService extends IntentService {
private static final String ACTION_UPLOAD_IMG = "yangyang";
public static final String EXTRA_IMG_PATH = "haha";
public static void startUploadImg(Context context, String path) {
Intent intent = new Intent(context, UploadImgService.class);
//要设置相同action才能启动
intent.setAction(ACTION_UPLOAD_IMG);
intent.putExtra(EXTRA_IMG_PATH, path);
//启动服务
context.startService(intent);
}
public UploadImgService() {
super("UploadImgService");
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
//判断消息是否一致
if (ACTION_UPLOAD_IMG.equals(action)) {
//通过EXTRA_IMG_PATH标志,获取数据
final String path = intent.getStringExtra(EXTRA_IMG_PATH);
handleUploadImg(path);
}
}
}
private void handleUploadImg(String path) {
try {
//模拟上传耗时操作,在intentservice里面不需要自己创建线程
Thread.sleep(3000);
Intent intent = new Intent(MainActivity.UPLOAD_RESULT);
intent.putExtra(EXTRA_IMG_PATH, path);
//发送广播
sendBroadcast(intent);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void onCreate() {
super.onCreate();
Log.e("TAG", "onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("TAG", "onDestroy");
}
}
MainActivity
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
public static final String UPLOAD_RESULT = "com.example.intent_service_MainActivity";
private LinearLayout mLine;
private BroadcastReceiver uploadImgReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() == UPLOAD_RESULT) {
String path = intent.getStringExtra(UploadImgService.EXTRA_IMG_PATH);
handleResult(path);
}
}
};
private void handleResult(String path) {
TextView tv = (TextView) mLine.findViewWithTag(path);
tv.setText(path + " 请求成功");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLine = (LinearLayout) findViewById(R.id.mLine);
registerReceiver();
}
private void registerReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(UPLOAD_RESULT);
registerReceiver(uploadImgReceiver, filter);
}
int i = 0;
public void addTask(View view) {
//模拟发送消息
String path = "这是我发送第" + (++i) + "条消息";
//调用IntentService方法,传入路径
UploadImgService.startUploadImg(this, path);
TextView tv = new TextView(this);
//把TextView添加到LineLayout当中
mLine.addView(tv);
tv.setText(path + " 请求消息中");
tv.setTag(path);
}
@Override
protected void onDestroy() {
super.onDestroy();
//我用的广播来发送消息,所以退出的时候要解除广播
unregisterReceiver(uploadImgReceiver);
}
}
xml布局:
<LinearLayout
android:id="@+id/mLine"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="addTask"
android:text="发送请求" />
</LinearLayout>
最后要在配置清单注册,不注册的话是不会执行其中的方法。
带大家了解一下源码:
可以看到IntentService是基于Service来实现的,就是每次调用onStartCommand的时候,通过mServiceHandler发送一个消息,消息中包含我们的intent。然后在该mServiceHandler的handleMessage中去回调onHandleIntent(intent);就可以了。
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
super();
mName = name;
}
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}
具体点来说就是在onStartCommand中回调了onStart,onStart中通过mServiceHandler发送消息到该handler的handleMessage中去。最后handleMessage中回调onHandleIntent(intent)。回调完成后回调用 stopSelf(msg.arg1),注意这个msg.arg1是个int值,相当于一个请求的唯一标识。每发送一个请求,会生成一个唯一的标识,然后将请求放入队列,当全部执行完成(最后一个请求也就相当于getLastStartId == startId)。
在源码里面可以看到在onstart()方法和onStartCommand()方法中,都声明了一个int startId; 的参数,或者当前发送的标识是最近发出的那一个(getLastStartId == startId),则会销毁我们的Service.如果传入的是-1则直接销毁。那么,当任务完成销毁Service回调onDestory,可以看到在onDestroy中释放了我们的Looper:mServiceLooper.quit()。(这也把不用关闭service说清楚了,喜欢的朋友给大家分享一下吧)
public interface Callback {
/**
* @param msg A {@link android.os.Message Message} object
* @return True if no further handling is desired
*/
public boolean handleMessage(Message msg);
}
在IntentService里面不需要开启线程是因为在底层封装了一个Handler,在handler里面写一个Callback接口,而且子类必须实现这个接收消息。
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。