下面我将为您详细讲解“Android Studio后台服务使用详解”的完整攻略。
什么是Android Studio后台服务
Android应用在使用时,可能需要执行一些后台任务,比如网络请求、数据上传、数据下载等操作。而这些操作可能需要在应用关闭时仍然能够运行,这时就需要使用到Android的后台服务。
Android后台服务是在应用关闭或者在后台运行时,在后台执行一些任务,比如播放音乐、上传数据等操作。Android Studio提供了后台服务的API,可以方便地将这些任务放到后台运行,不受前台界面的影响。
如何使用Android Studio后台服务
使用Android Studio后台服务需要经过以下步骤:
步骤1
在AndroidManifest.xml
中声明服务。如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application
...>
<service
android:name=".MyService"
android:enabled="true"
android:exported="false" />
</application>
</manifest>
注意:需要在服务的名称后加上.
,表示在当前应用程序包内。
步骤2
新建一个服务类,继承自Service
类。如下:
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
// 服务逻辑执行
...
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
在这个服务类中,你可以执行你需要在后台运行或者在应用关闭后仍需要运行的任务。
步骤3
在主界面调用服务,可以在Activity中使用startService()
方法启动服务。如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 启动MyService服务
startService(new Intent(this, MyService.class));
}
}
步骤4
在服务逻辑执行完成后,需要通过stopSelf()
方法或者stopService()
方法来停止服务。
stopService(new Intent(this, MyService.class));
示例说明
示例1
一个后台服务的示例是在应用关闭时仍然在后台运行。
服务类代码:
public class MusicService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 播放音乐
...
// 指定为START_STICKY的时候,Service在被Process.killProcess杀掉后,系统会尝试重启该Service,
// 因为Service的状态标记为START_STICKY或START_REDELIVER_INTENT的情况下,
// 当Service进程被杀时,会重新启动Service,并将Intent对象全部重新传入,以保证任务可以继续执行。
return START_STICKY;
}
@Override
public void onDestroy() {
// 停止播放
...
}
}
调用服务的代码:
Intent intent = new Intent(MainActivity.this, MusicService.class);
startService(intent);
示例2
一个下载文件的后台服务示例。
服务类代码:
public class DownloadService extends Service {
private DownloadTask downloadTask;
private String downloadUrl;
public DownloadService() {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
downloadUrl = intent.getStringExtra("download_url");
downloadTask = new DownloadTask();
downloadTask.execute(downloadUrl);
return super.onStartCommand(intent, flags, startId);
}
private class DownloadTask extends AsyncTask<String, Integer, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// 显示通知
showNotification();
}
@Override
protected String doInBackground(String... params) {
String downloadUrl = params[0];
int fileLength = 0;
int downloadLength = 0;
InputStream inputStream = null;
OutputStream outputStream = null;
HttpURLConnection connection = null;
String filePath = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/temp.apk";
try {
URL url = new URL(downloadUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
if (connection.getResponseCode() == 200) {
fileLength = connection.getContentLength();
inputStream = connection.getInputStream();
outputStream = new FileOutputStream(filePath);
byte[] buffer = new byte[2048];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
downloadLength += len;
publishProgress(downloadLength * 100 / fileLength);
}
outputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
return filePath;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
int progress = values[0];
// 更新通知栏进度条
notificationManagerCompat.notify(1, getNotification(progress));
}
@Override
protected void onPostExecute(String filePath) {
super.onPostExecute(filePath);
// 下载完成,取消通知
notificationManagerCompat.cancel(1);
// 开始安装应用
installAPK(DownloadService.this, filePath);
}
}
private Notification getNotification(int progress) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "download");
builder.setContentTitle("app正在下载")
.setSmallIcon(R.drawable.ic_launcher_background)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setProgress(100, progress, false);
return builder.build();
}
private void showNotification() {
NotificationChannel channel = new NotificationChannel(
"download",
"download",
NotificationManager.IMPORTANCE_HIGH
);
notificationManagerCompat.createNotificationChannel(channel);
Notification notification = getNotification(0);
notificationManagerCompat.notify(1, notification);
}
private static void installAPK(Context context, String filePath) {
File file = new File(filePath);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//部分机型更新出错,fileprovider 异常处理 2020-06-10 crl
uri = FileProvider.getUriForFile(context.getApplicationContext(), "xxxxx.fileProvider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
uri = Uri.fromFile(file);
}
intent.setDataAndType(uri, "application/vnd.android.package-archive");
context.startActivity(intent);
}
}
调用服务的代码:
String downloadUrl = "http://xxx.com/xxx.apk";
Intent intent = new Intent(MainActivity.this, DownloadService.class);
intent.putExtra("download_url", downloadUrl);
startService(intent);
以上是关于Android Studio后台服务使用详解的完整攻略,希望能对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:android studio后台服务使用详解 - Python技术站