1. service 是Android 四大组件之一,和activity非常相似,都有自己的生命周期,运行在后台,没有用户特点。
2. activity和service的区别
activity:表示可见的用户界面,和布局相关联
service:没有用户界面,一直在后台运行,通常做耗时操作,activity销毁不会影响这个操作。
3. activity 和 service 选择的标准:
当系统获取的网络数据需要与用户进行交互时或者展示给用户时,就需要用到activity。
当网络获取的数据的过程不需要展示给用户,在完成后通知用户结果就可以,就用到service
4. service 的特点
运行在后台是不可见的
优先级是高于activty的
5. service 的用途
播放音乐
用于记录地址位置的改变
下载大文件
6. service 使用的注意事项
service 运行在主线程中,不能够直接的做耗时操作
如果需要做耗时凑哦,就在方法中开启工作线程
7 据api描述
service不是一个单独的进程,除非单独声明,否则他和运行他的应用程序在同一个进程当中。
service 不是一个线程,它运行在主线程当中,避免anr错误。
结论:service不是进程也不是线程,service和thread都是进程当中的一部分
8.进程:应用程序在运行时被分配的内存空间,是最小的资源分配单位。
线程:最小的执行单元,执行路径
线程所需要的资源都是他所在的进行进行获取的。
9.service和thread之间有什么区别?
thread:是线程中程序执行的最小单位,我们可以通过thread来做一些异步的操作。
service:是android的一个机制,如果是本地的service运行在应用程序的主线程当中,
如果是远程service,就运行在一个单独的进程当中。
thread是独立运行的,如果创建线程的activity被finish了,而线程没有被停止,而且其run方法
当中的任务没有执行完,那么线程就会一值执行下去,这个时候就会出现问题了,activity被销毁了,
就无法获得线程的引用了,就无法控制线程了,然后就内存泄漏的,不同的activity不能够对同一个
线程进行控制。
可以把service想象成一种消息服务,在耗时操作结束之后,可以通过handler或者发送广播的方式,
通知activity,然后更新界面数据。
10.服务的种类:
1.本地服务 (Local Service)
在应用程序内部使用
2.远程服务 (Romote Service)
android系统内部的应用程序之间进行数据的交换,通过iBinder接口,实现数据的交换。
11.创建和配置服务
1.写一个类,继承Service
2.重写onBind()方法
3.在清单文件当中注册服务
12.启动服务的生命周期 context.startService(intent);
onCreate------>onStartCommend()------>onDestroy()
当服务被创建时会回调onCreate方法,当服务被启动时会回调onStartCommend,多次启动一个已有的服务,
就不会调用onCreate方法了,但是每次都会调用onStartCommend方法,停止服务时,会回调onDestory的方法。
13.startService启动服务的特点:
1.启动源和service之间是没有关系的。
2.无法在启动源当中获得service的对象。
14.如果启动源和service之间有关系,需要实现数据的交互,就不能通过startService和stopService开启关闭服务,
要通过bindService和unbindService来绑定和解除绑定服务。
15.绑定服务生命周期的流程:
onCreate------>onBind------>onUnbind------>onDestroy
16.绑定服务bindService的特点:
1.相当于客户端与服务器的交互模式,运行被绑定组件和服务之间的交互,并且远程服务的访问。
2.应用程序的组件绑定服务时,服务就会自动创建运行。
3.多个应用程序的组件都可以绑定服务,当服务销毁时就会解除绑定,当绑定的组件销毁时,
服务也会销毁,当多个组件绑定服务时,多个组件销毁时,服务才会销毁。
bindService(intent,conn,flag);
intent: 意图对象,包括想要绑定的服务的信息
conn:就是ServiceConnection子类的对象,用来监听访问者与服务对象的连接状态的。
onServiceConnection:服务连接后会回调的方法
onServiceDisconnected:服务断开连接后会回调的方法。
flags:常量,指代绑定时是否自动创建service对象,
BIND_AUTO_CREATE(自动创建)
1.远程服务
2.百度地图
3.屏幕适配
4.动画
5.自定义view
作业:
1.仿照版本迭代
apk:
apk下载地址
http://218.244.149.129:9010/download.php?apkid=12
跳转安装界面
package com.lional.day0923_homework;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import com.lional.day0923_homework.utils.SDCardHelper;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
public class DownLoodService extends Service{
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
final String path = intent.getStringExtra("path");
new Thread(){
private HttpURLConnection httpConn;
private BufferedInputStream bis;
public void run() {
try {
URL url2 = new URL(path);
httpConn = (HttpURLConnection) url2
.openConnection();
httpConn.setDoInput(true); //允许输入内容
httpConn.setDoOutput(false);
httpConn.connect();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (httpConn.getResponseCode()==200) {
int totallenth = httpConn.getContentLength();
bis = new BufferedInputStream(httpConn.getInputStream());
NotificationManager manager = (NotificationManager) DownLoodService.this.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(DownLoodService.this);
builder.setContentTitle("下载文件");
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentText("正在下载中...");
byte[] buffer = new byte[8*1024];
int c = 0;
int i = 0;
//int tl = (int) (totallenth/(8*1024));
while ((c=bis.read(buffer))!=-1) {
i+=c;
builder.setProgress(totallenth, i, false);
// 发送通知
manager.notify(1, builder.build());
baos.write(buffer, 0, c);
baos.flush();
}
byte[] data = baos.toByteArray();
String fileName = path.substring(path.lastIndexOf("/")+1);
SDCardHelper.saveFileToSDCardCacheDir(data, fileName, DownLoodService.this);
manager.cancel(1);
builder = new NotificationCompat.Builder(DownLoodService.this);
builder.setPriority(Notification.PRIORITY_HIGH);
builder.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("下载").setContentText("下载成功");
manager.notify(2, builder.build());
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
File file = DownLoodService.this.getExternalCacheDir();
intent.setDataAndType(Uri.fromFile(new File(file, fileName)), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
DownLoodService.this.startActivity(intent);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if (bis!=null) {
bis.close();
}
if (httpConn!=null) {
httpConn.disconnect();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
return super.onStartCommand(intent, flags, startId);
}
}
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
点击activity当中的按钮,通过服务下载apk,把下载的进度显示在通知当中。下载完成后切换通知为下载完成。然后点击可以安装。
public class MainActivity extends Activity {
String path = "http://218.244.149.129:9010/upload/apk/sinoglobalbaseNew.apk";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void downLoad(View v){
Intent intent = new Intent(this, DownLoodService.class);
intent.putExtra("path", path);
startService(intent);
}
}