扩展IntentService类的使用

导读:

        1. 当我们的服务需要多线程运行时,需要使用扩展Service类,对于每一个启动请求它都用一个工作线程处理任务,并且每次只处理一个请求。

        2.当我们的服务需要通过一个工作队列来处理启动请求时,可以使用扩展IntentService类。

         该Service会在需要的时候创建,当完成所有的任务以后自己关闭,且请求是在工作线程处理的。这么说,我们使用了IntentService最起码有两个好处,一方面不需要自己   去new Thread了;另一方面不需要考虑在什么时候关闭该Service了。

  

  那么扩展IntentService的执行步骤:

   这是Service类的子类,它使用了工作(worker)线程来处理所有的启动请求,每次请求都会启动一个线程。 如果服务不需要同时处理多个请求的话,这是最佳的选择。 所有你要做的工作就是实现onHandleIntent()即可,它会接收每个启动请求的intent,然后就可在后台完成工作。



创建一个缺省的工作(worker)线程,它独立于应用程序主线程来执行所有发送到onStartCommand()的intent。

创建一个工作队列,每次向你的onHandleIntent()传入一个intent,这样你就永远不必担心多线程问题了。

在处理完所有的启动请求后,终止服务,因此你就永远不需调用stopSelf()了。

提供缺省的onBind()实现代码,它返回null。

提供缺省的onStartCommand()实现代码,它把intent送入工作队列,稍后会再传给你的onHandleIntent()实现代码。

以上所有步骤将汇成一个结果:你要做的全部工作就是实现onHandleIntent()的代码,来完成客户端提交的任务。(当然你还需要为服务提供一小段构造方法。)

以下是个IntentService的实现例程:

public class HelloIntentService extends IntentService {

  /** 
   * 构造方法是必需的,必须用工作线程名称作为参数
   * 调用父类的[http://developer.android.com/reference/android/app/IntentService.html#IntentService(java.lang.String) IntentService(String)]构造方法。
   */
  public HelloIntentService() {
      super("HelloIntentService");
  }

  /**
   * IntentService从缺省的工作线程中调用本方法,并用启动服务的intent作为参数。 
   * 本方法返回后,IntentService将适时终止这个服务。
   */
  @Override
  protected void onHandleIntent(Intent intent) {
      // 通常我们会在这里执行一些工作,比如下载文件。
      // 作为例子,我们只是睡5秒钟。
      long endTime = System.currentTimeMillis() + 5*1000;
      while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
                  wait(endTime - System.currentTimeMillis());
              } catch (Exception e) {
              }
          }
      }
  }
}

所有你需要做的就是:一个构造方法和一个onHandleIntent()方法的实现。

如果你还决定重写其它的回调方法,比如onCreate()onStartCommand()onDestroy(), 请确保调用一下父类的实现代码,以便IntentService能正确处理工作线程的生命周期。

比如说,onStartCommand()必须返回缺省实现代码的结果(缺省代码实现了如何获取传给onHandleIntent()的intent):

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
    return super.onStartCommand(intent,flags,startId);
}

除了onHandleIntent()以外,唯一不需要调用父类实现代码的方法是onBind()(不过如果你的服务允许绑定,你还是需要实现它)。


/**********************************************************以下是一个模拟上传图片的DEMO***************************************************************************************/

出现情景:当我们上传多张图片,在上传过程中,我们可能将应用置于后台,去做别的,这时我们的Activity可能会被杀死,所以我们需要将上传图片这个操作交给Service来实现,优点还有是:当服务被杀死,我们还可以通过设置 startForeground(int,Notification)设置优先级。

Service

package com.intentservice;

import com.example.uploadimage.MainActivity;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
/**
 * IntentService:会在需要时自动开启线程去操作耗时任务,但操作完成时会自动关闭:因此IntentService不需要我们自己亲自去管理,使用起来比较方便
 * @author galaxy
 *
 */
public class UploadImgService extends IntentService {
    
    private static final String ACTION_UPLOAD_IMG = "com.intentservice.action.UPLOAD_IMAGE";
    public static final String EXTRA_IMG_PATH = "com.intentservice.extra.IMG_PATH";
    
    
   
    public static void startUploadImg(Context context,String path){
        Intent intent = new Intent();
        intent.setAction(ACTION_UPLOAD_IMG);
        intent.putExtra(EXTRA_IMG_PATH, path);
        context.startService(intent);
        
           Log.e("jg", "UploadImgService-----startUploadImg");
          
    }
    
   @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub
        super.onStart(intent, startId);
    }
   /*构造方法的参数必须是工作线程名称*/
    public UploadImgService() {
        super("UploadImgService");
        
        
    }
    
    
    /*
     * 缺省的onStartCommand()将intent送入到工作队列中,然后在传给onHandleIntent
     */
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.e("jg", "UploadImgService-----onHandleIntent");
        if(intent != null){
            final String action = intent.getAction();
            if(ACTION_UPLOAD_IMG.equals(action)){
                final String path = intent.getStringExtra(EXTRA_IMG_PATH);
                handleUploadImg(path);
            }
        }
        
    }
    
    /**
     * 书写一个方法,用来执行上传 这个动作
     * @param path: 要上传到的路径
     */
    public void handleUploadImg(String path){
        try {
            Thread.sleep(3000);//模拟上传耗时
            
            Intent intentUpload = new Intent(MainActivity.UPLOAD_RESULT);//参数说明:给这个intent加一个标识,上传结果
            intentUpload.putExtra(EXTRA_IMG_PATH, path);
            
             System.out.println("上传的路径-handleUploadImg-->"+path);
            //使用广播,通知Activity,Service的任务完成状态
            sendBroadcast(intentUpload);
            
            
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
    }
    

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
    }

}


Activity

package com.example.uploadimage;

import com.intentservice.UploadImgService;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
 * 实现一个使用IntentService在后台上传图片的功能   (注:Service与Activity之间的通信我们可以选择使用广播)
 * @author galaxy
 *
 */
public class MainActivity extends  Activity{//在主线程里发送请求

     public static final String UPLOAD_RESULT = "com.intentservice.UPLOAD_RESULT";
    
     private LinearLayout mLyTaskContainer;
    
     BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){

            @Override
            public void onReceive(Context context, Intent intent) {
                 //Intent broadCastIntent = getIntent();
                 if(intent.getAction()==UPLOAD_RESULT){
                     final String path = intent.getStringExtra(UploadImgService.EXTRA_IMG_PATH);
                    
                     handleResult(path);
                    
                 }
            }
            
        };
        
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mLyTaskContainer= (LinearLayout) findViewById(R.id.id_ll_taskcontainer);
        
    
        //注册 添加标记的 广播
        registReceiver();
        
    }
     
    private void registReceiver(){
        IntentFilter filter = new IntentFilter();
        filter.addAction(UPLOAD_RESULT);
        
        registerReceiver(mBroadcastReceiver, filter);
            
    }
    
    
     int i = 0;
     public void addTask(View view)
        {
            //模拟路径
            String path = "/sdcard/imgs/" + (++i) + ".png";
            UploadImgService.startUploadImg(MainActivity.this, path);
            

            TextView tv = new TextView(this);
            mLyTaskContainer.addView(tv);
            tv.setText(path + " is uploading ...");
            tv.setTag(path);
        }
    

    /**
     * 处理
     * @param path
     */
    public void handleResult(String path){
        TextView tv = (TextView) mLyTaskContainer.findViewWithTag(path);
        
        tv.setText(path + " upload success ~~~ ");
        
    }
    
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        
        unregisterReceiver(mBroadcastReceiver);
    }

}


布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:id="@+id/id_ll_taskcontainer"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="startTask"
        android:textSize="25sp"
        android:background="#FF83FA"
         android:onClick="addTask"
        />

</LinearLayout>

这里尤其注意的地方:

在Manifest.xml文件的<application>节点中注册Service和设置intent-filter

 <service
            android:name="com.intentservice.UploadImgService"
            >
            <intent-filter>
                <action android:name="com.intentservice.action.UPLOAD_IMAGE" />
            </intent-filter>

        </service>

因为项目中设置了action,所以在注册的时候没有添加 <action android:name="com.intentservice.action.UPLOAD_IMAGE" />,当时真是快崩溃了~~~~

源码地址:点击打开链接


参考网址:http://blog.csdn.net/lmj623565791/article/details/47143563

                    http://www.android-doc.com/guide/components/services.html#.E6.89.A9.E5.B1.95IntentService.E7.B1.BB









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值