单例模式
总体思路:先创建一个私有的private static 的对象,再创建一个私有的构造,防止外部调用修改;最后创建一个对外开放的静态的对象实例,返回值为return 对象;
饿汗式是先new出对象,等待调用;懒汉式是先创建对象为null,之后等待调用,只有当被调用时才会new出对象
饿汗式
//饿汗式
private static Utils utils = new Utils();
//私有构造
private Utils(){
}
//提供对外公开的方法
public static Utils getInstance(){
return utils;
}
懒汉式
需要上锁,双重校验锁,否则会造成线程安全问题
//懒汉式
private static Utils utils = null;
//私有构造
private Utils(){
}
//提供对外公开的方法
private static Utils getInstance(){
if (utils == null) {
synchronized (Object.class){
if (utils == null) {
utils = new Utils();
}
}
}
return utils;
}
断点续传
2次请求,第一次获取文件总长度,第二次获取从SD卡中获取的文件长度并继续用随机流下载
package com.example.work;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MyThread extends Thread {
private static final String TAG = "---";
private String path;
private String str_url;
private Handler handler;
public MyThread(String path, String str_url, Handler handler) {
this.path = path;
this.str_url = str_url;
this.handler = handler;
}
private long end; //总长度
private long start; //SD卡文件的长度
@Override
public void run() {
try {
URL url = new URL(str_url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
int responseCode = connection.getResponseCode();
Log.i(TAG, "code: "+responseCode);
if (responseCode == 200) {
end = connection.getContentLength();
}
} catch (Exception e) {
e.printStackTrace();
}
File file = new File(path);
if(file.exists()){
start = file.length();
}else{
start = 0;
}
try {
URL url = new URL(str_url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Range","bytes="+start+"-"+end);
connection.connect();
int responseCode = connection.getResponseCode();
Log.i(TAG, "code: "+responseCode);
Log.i(TAG, "run: "+start+" - "+end);
if (responseCode == 206) {
int len = 0;
byte[] b = new byte[1024];
InputStream is = connection.getInputStream();
RandomAccessFile randomAccessFile = new RandomAccessFile(path,"rw");
randomAccessFile.seek(start);
long count = start;
while((len = is.read(b)) != -1){
randomAccessFile.write(b, 0, len);
count += len;
int values = (int) ((float)count/end*100);
Message msg = Message.obtain();
msg.what = 0;
msg.obj = values;
Log.i(TAG, "values: "+values);
handler.sendMessage(msg);
}
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
综合技能
package com.example.work;
import android.Manifest;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.google.gson.Gson;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ListView listView;
private MyAdapter adapter;
private String path2 = "http://www.qubaobei.com/ios/cf/dish_list.php?stage_id=1&limit=20&page=1";
public static List<String> isLoad = new ArrayList<>();
private List<JavaBean.DataBean> dataList = new ArrayList<>();
public static List<String> name = new ArrayList<>();
private int index = 0;
private ProgressDialog progressDialog;
private File directory;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
isLoad.set(index,"已下载");
adapter.notifyDataSetChanged();
} else if (msg.what == 1) {
progressDialog.setProgress((Integer) msg.obj);
progressDialog.dismiss();
if((Integer) msg.obj == 100){
Toast.makeText(MainActivity.this, "下载成功!", Toast.LENGTH_SHORT).show();
}
} else if (msg.what == 2) {
Toast.makeText(MainActivity.this, "已经下载过了", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}
};
private long start = 0;
private long end = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 1000);
initView();
}
private void initView() {
listView = (ListView) findViewById(R.id.list_view);
adapter = new MyAdapter(dataList,MainActivity.this);
listView.setAdapter(adapter);
new MyAsyncTask(dataList,adapter).execute(path2);
listListener();
}
private void listListener() {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
MyDialog(position);
}
});
}
private void MyDialog(final int position) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("是否下载?");
builder.setTitle("提示信息");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("下载中。。。");
index = position;
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(dataList.get(position).getPic());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if (connection.getResponseCode() == 200) {
end = connection.getContentLength();
}
} catch (Exception e) {
e.printStackTrace();
}
directory = Environment.getExternalStorageDirectory();
File file = new File(directory, name.get(position));
if (file.exists()) {
start = file.length();
}else{
start = 0;
}
if(start == end){
handler.sendEmptyMessage(2);
return;
}
try {
URL url = new URL(dataList.get(position).getPic());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Range","bytes="+start+"-"+end);
connection.connect();
if (connection.getResponseCode() == 206) {
int len = 0;
byte[] b = new byte[1024];
InputStream is = connection.getInputStream();
FileOutputStream fos = new FileOutputStream(new File(directory,name.get(position)));
long count = start;
while ((len = is.read(b)) != -1) {
// Thread.sleep(1000);
fos.write(b, 0, len);
count += len;
int values = (int) ((float)count/end*100);
Message obtain = Message.obtain();
obtain.what = 1;
obtain.obj = values;
handler.sendMessage(obtain);
}
handler.sendEmptyMessage(0);
connection.disconnect();
is.close();
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
progressDialog.show();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
}
本文详细解析了单例模式的两种实现方式——饿汉式与懒汉式,并探讨了它们在线程安全方面的考量。此外,还介绍了如何在Android应用中实现文件的断点续传功能,包括通过HTTP请求获取文件总长度和断点位置,以及使用随机流进行文件下载。
2万+

被折叠的 条评论
为什么被折叠?



