Demo基本功能展示
具体过程
思路
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
代码
xml视图代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="400dp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:context="MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="点我捆绑下载"
/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button"
android:layout_centerInParent="true"
android:text="还没开始加载!" />
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/text"
android:max="100"
android:progress="0" />
<Button
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/progress_bar"
android:layout_centerInParent="true"
android:text="不展示图片" />
</RelativeLayout>
<ImageView
android:id="@+id/iv_picture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/relativeLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
服务的代码
package com.chris.servicedownloadpictest;
public interface DownloadListener {
void processDownload(int i);
void success();
void failure();
}
package com.chris.servicedownloadpictest;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MyDownloadAsyncTask extends AsyncTask<String,Integer,Boolean> {
public static String filePath = "";
public static Bitmap loadBitmap;
public static final int TYPE_SUCCESS = 0;
public static final int TYPE_FAILED = 1;
public static final int TYPE_PAUSED = 2;
public static final int TYPE_CANCELED = 3;
private DownloadListener listener;
private boolean isCancelled = false;
private boolean isPaused = false;
private int lastProgress;
public MyDownloadAsyncTask(DownloadListener downloadListener) {
this.listener = downloadListener;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Boolean doInBackground(String... strings) {
InputStream is = null;
RandomAccessFile accessFile = null;
File file = null;
long downloadedLength = 0;
String downloadUrl = strings[0];
String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
filePath = directory + fileName;
file = new File(filePath);
if (file.exists()) {
downloadedLength = file.length();
}
try {
long contentLength = getContentLength(downloadUrl);
if (contentLength == 0) {
return false;
} else if (contentLength == downloadedLength) {
return true;
}
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.addHeader("RANGE", "bytes=" + downloadedLength + "-")
.url(downloadUrl)
.build();
Response response = client.newCall(request).execute();
if (response != null) {
is = response.body().byteStream();
accessFile = new RandomAccessFile(file, "rw");
accessFile.seek(downloadedLength);
byte[] b = new byte[1024];
int total = 0;
int len;
while ((len = is.read(b)) != -1) {
total += len;
accessFile.write(b, 0, len);
int progress = (int) ((total + downloadedLength) * 100 / contentLength);
publishProgress(progress);
}
response.body().close();
return true;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (accessFile != null) {
accessFile.close();
}
Log.d("TAG", "这里永远都会执行 ");
if (isCancelled && file != null) {
file.delete();
}
FileInputStream fileInputStream = new FileInputStream(filePath);
loadBitmap = BitmapFactory.decodeStream(fileInputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
private long getContentLength(String downloadUrl) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(downloadUrl)
.build();
Response response = client.newCall(request).execute();
if (response != null && response.isSuccessful()) {
long contentLength = response.body().contentLength();
response.close();
return contentLength;
}
return 0;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
listener.processDownload(values[0]);
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if(aBoolean){
listener.success();
}else{
listener.failure();
}
}
}
package com.chris.servicedownloadpictest;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import androidx.annotation.Nullable;
public class MyService extends Service {
private MyDownloadAsyncTask downloadTask;
private MyBinder myBinder = new MyBinder();
public MyService() {
}
public class MyBinder extends Binder{
void startDownload(String url ,DownloadListener listener){
downloadTask = new MyDownloadAsyncTask(listener);
downloadTask.execute(url);
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
}
Activity
package com.chris.servicedownloadpictest;
import androidx.appcompat.app.AppCompatActivity;
import android.app.DownloadManager;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.net.URL;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button button;
private TextView text;
private ProgressBar progressBar;
private Button cancel;
private ImageView ivPicture;
private DownloadListener listener;
private MyService.MyBinder binder;
private MyService service;
final static String URL_STRING = "https://developer.android.google.cn/images/service_lifecycle.png";
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
binder = (MyService.MyBinder) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initListener();
initService();
}
private void initService() {
Intent intent = new Intent(MainActivity.this,MyService.class);
bindService(intent,serviceConnection,BIND_AUTO_CREATE);
}
private void startDownload() {
binder.startDownload(URL_STRING,listener);
}
private void initListener() {
listener = new DownloadListener() {
@Override
public void processDownload(int i) {
text.setText(String.valueOf(i));
progressBar.setProgress(i);
}
@Override
public void success() {
ivPicture.setImageBitmap(MyDownloadAsyncTask.loadBitmap);
text.setText("下载成功");
}
@Override
public void failure() {
text.setText("Download fail");
}
};
}
private void initViews() {
button = findViewById(R.id.button);
text = findViewById(R.id.text);
progressBar = findViewById(R.id.progress_bar);
cancel = findViewById(R.id.cancel);
ivPicture = findViewById(R.id.iv_picture);
button.setOnClickListener(this);
cancel.setOnClickListener(this);
}
static Boolean isCancel = false;
@Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.button:
startDownload();
break;
case R.id.cancel:
if(!isCancel){
ivPicture.setVisibility(View.INVISIBLE);
cancel.setText("展示图片");
isCancel = true;
}else {
ivPicture.setVisibility(View.VISIBLE);
cancel.setText("不展示图片");
isCancel = false;
}
break;
}
}
}