Android - Service(三)之 IntentService

IntentService

  1. IntentService 继承自 Service,它使用一个 WorkerThread 来处理异步请求,每次处理一个请求;
  2. IntentService 内部开启了一个子线程,专门用于执行耗时操作;
  3. 当所有请求处理完毕时,IntentService 会自己停止服务;
  4. 要使用 IntentService,必须自定义一个类,继承自 IntentService,实现 onHandleIntent() 方法,并需要有一个无参的构造方法且调用 super(String name)
  5. onHandleIntent() 方法运行在子线程当中,如果多次启动服务(即开启多个子线程),则各个子线程会依次排队执行,当所有的子线程执行完毕,IntentService 会自动停止服务,因此 IntentService 适合用来执行单线程操作。

下面使用 IntentService 来从网络下载这张图片:

Android - Service(三)之 IntentService_第1张图片

1. 使用一个 Activity 来启动服务,其主界面布局文件,activity_main:




    

2. MainActivity.java:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // 此方法用来启动一个 IntentService,用来下载图片
    public void downloadImage(View view) {
        Intent intent = new Intent(MainActivity.this, DownloadService.class);
        startService(intent);
    }

}

3. 服务端程序,DownloadService.java:

/**
 * Created by Monkey.C on 2016/5/14.
 */
public class DownloadService extends IntentService {

    private final String TAG = "DownloadService";

    // 此构造方法必须要有,且需要调用 super(String name) 方法
    public DownloadService() {
        super("DownloadService");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        HttpURLConnection conn = null;
        InputStream is = null;
        File file = Environment.getExternalStoragePublicDirectory("Download");
        // 指定存放图片的路径及图片的名称
        File newFile = new File(file, "download.jpg");
        try {
            URL url = new URL("http://www.bz55.com/uploads/allimg/150824/139-150R41H233.jpg");
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(8000);
            conn.connect();
            if (conn.getResponseCode() == 200) {
                is = conn.getInputStream();
                byte[] buff = new byte[100];
                int len;
                // 将下载的图片写入到 SD 卡中
                FileOutputStream fos = new FileOutputStream(newFile);
                while ((len = is.read(buff)) != -1) {
                    fos.write(buff, 0, len);
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null || conn != null) {
                try {
                    conn.disconnect();
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

    // 当执行完成所有子线程之后,IntentService 会自己停止服务
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "图片下载完成!");
        Log.i(TAG, "onDestroy");
    }

}

4. 在 AndroidManifest.xml 中注册服务及声明权限:




    
    
    
    

    
        
            
                

                
            
        

        
    


5. 效果演示:

首先打开 Android Studio 自带的 Android Device Monitor,找到 mnt/media_rw/sdcard/Download,可以看到目前该目录下没有任何文件:

Android - Service(三)之 IntentService_第2张图片

接着启动程序,点击下载图片按钮,同时打开 logcat 窗口,观看日志:

Android - Service(三)之 IntentService_第3张图片

可以看到,当服务启动时,会调用 onCreate() 方法和onStartCommand() 方法,我们在 onDestroy() 方法里面加上一句 Log.i(TAG, "图片下载完成!");,可以看到,当图片下载完成之后,IntentService 会调用 onDestroy() 方法,即子线程执行完成之后,IntentService 会自动停止服务,无须我们手动停止服务。

接下来再次打开 Android Device Monitor,找到 mnt/media_rw/sdcard/Download,可以看到我们下载的图片已经在里面了:

Android - Service(三)之 IntentService_第4张图片

点击上图红色方框中的按钮,将图片导出到电脑,看是不是我们下载的图片:

OK,搞定。


参考资料:

  • Mars Android 视频 - Mars
  • 老罗 Android 开发视频 - 罗升阳
  • Bound Services邦定服务 - EarlyBird
  • 基础总结篇之四:Service完全解析 - Scott

你可能感兴趣的:(Android - Service(三)之 IntentService)