import android.content.Intent;
import android.net.Uri; import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap; /**
* 下载的管理类
*/ public class MyDownloadManager { public static final int STATE_NONE = 0;//未下载
public static final int STATE_WAITING = 1;//等待中
public static final int STATE_DOWNLOADING= 2;//下载中
public static final int STATE_PAUSED= 3;//下载暂停
public static final int STATE_SUCCESS = 4;//下载成功
public static final int STATE_ERROR = 5;//下载失败 private MyDownloadManager() {} private static MyDownloadManager instance; public synchronized static MyDownloadManager getInstance() {
if (instance == null) {
instance = new MyDownloadManager();
}
return instance;
} public HashMap<String, DownloadInfo> mSavedDownloadInfo = new HashMap<>();
public HashMap<String, DownloadTask> mSavedDownloadTask = new HashMap<>(); //对于AppInfo来说,downloadUrl、size、id、name、packageName
//存在本地的路径,当前下载的状态,当前下载的进度
public void startDownload(AppInfo info) {
//需要将downloadInfo缓存起来,以便我们继续下载的时候来使用
DownloadInfo downloadInfo = mSavedDownloadInfo.get(info.id);//DownloadInfo.createDownloadInfoFromAppInfo(info);
if(downloadInfo == null) {
downloadInfo = DownloadInfo.createDownloadInfoFromAppInfo(info);
mSavedDownloadInfo.put(info.id, downloadInfo);
} //开始真正的下载了
DownloadTask task = new DownloadTask(downloadInfo);
mSavedDownloadTask.put(info.id, task);
downloadInfo.currentState = MyDownloadManager.STATE_WAITING;
notifyDownloadStateChanged(downloadInfo);
MyThreadPoolManager.getInstance().execute(task); } public void pauseDownload(AppInfo data) {
//暂停下载
DownloadInfo downloadInfo = mSavedDownloadInfo.get(data.id);
downloadInfo.currentState = STATE_PAUSED; //如果有一个任务已经丢到了线程池中,但是run方法还没有执行
//将任务从等待区域中移除
DownloadTask task = mSavedDownloadTask.get(data.id);
MyThreadPoolManager.getInstance().cancle(task); } public void installApk(AppInfo data) {
DownloadInfo downloadInfo = mSavedDownloadInfo.get(data.id);
//打开系统的安装界面
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(
Uri.fromFile(new File(downloadInfo.filePath)),
"application/vnd.android.package-archive");
UiUtils.getContext().startActivity(intent);
} class DownloadTask implements Runnable { private DownloadInfo downloadInfo; public DownloadTask(DownloadInfo downloadInfo) {
this.downloadInfo = downloadInfo;
} @Override
public void run() {
FileOutputStream fos = null;
try {
//由于是由线程池来进行管理的,所以只有走到了run方法才代表这个任务被线程池中的线程执行
downloadInfo.currentState = MyDownloadManager.STATE_DOWNLOADING;
notifyDownloadStateChanged(downloadInfo);
//区分一下是否是第一次下载
File downloadFile = new File(downloadInfo.filePath);
//下载apk
String url = "";
if(!downloadFile.exists()
||downloadInfo.currentPosition==0
||(downloadInfo.currentPosition!=0&&downloadInfo.currentPosition != downloadFile.length())) {
//第一次下载
downloadFile.delete();
downloadInfo.currentPosition = 0;
url = HttpHelper.URL + "download?name=" + downloadInfo.downloadUrl;
} else {
//代表的是断电下载,告诉服务器从这个文件的哪个位置开始给我吐数据
url = HttpHelper.URL + "download?name=" + downloadInfo.downloadUrl+"&range=" + downloadInfo.currentPosition;
} HttpHelper.HttpResult httpResult = HttpHelper.download(url);
if(httpResult != null) {
//获取文件的输入流
InputStream inputStream = httpResult.getInputStream();
if(inputStream != null) {
//第二个参数必须传true,否则的话,就会覆盖之前已经下载好的那一小部分文件
fos = new FileOutputStream(downloadFile,true);
byte[] buffer = new byte[1024];//30
int length = 0;
while((length = inputStream.read(buffer)) != -1 && downloadInfo.currentState == STATE_DOWNLOADING) {
fos.write(buffer, 0, length);
downloadInfo.currentPosition = downloadInfo.currentPosition + length;
notifyDownloadProgressChanged(downloadInfo);
fos.flush();
} //下载完成
//判断一下下载是否成功
long serverFileSize = Long.parseLong(downloadInfo.size);
long localFileSize = downloadInfo.currentPosition;
if(serverFileSize == localFileSize) {
//下载成功
downloadInfo.currentState = STATE_SUCCESS;
notifyDownloadStateChanged(downloadInfo);
} else { if(downloadInfo.currentState == STATE_PAUSED) {
//2、下载暂停
downloadInfo.currentState = STATE_PAUSED;
notifyDownloadStateChanged(downloadInfo);
} else {
//1、下载失败
downloadInfo.currentState = STATE_ERROR;
notifyDownloadStateChanged(downloadInfo);
}
} } else {
//此时代表服务器访问成功,但是服务器找不到你所要下载的文件
//下载失败
downloadInfo.currentState = STATE_ERROR;
notifyDownloadStateChanged(downloadInfo);
} } else {
//下载失败
downloadInfo.currentState = STATE_ERROR;
notifyDownloadStateChanged(downloadInfo);
} } catch (Exception e) {
downloadInfo.currentState = STATE_ERROR;
notifyDownloadStateChanged(downloadInfo);
} finally {
IOUtils.close(fos);
} }
} public interface DownloadObserver{
public void onDownloadStateChanged(DownloadInfo downloadInfo);
public void onDownloadProgressChanged(DownloadInfo downloadInfo);
} private ArrayList<DownloadObserver> observers = new ArrayList<>(); public void addDownloadObserver(DownloadObserver observer) {
if(observer != null && !observers.contains(observer)) {
observers.add(observer);
}
} private void notifyDownloadStateChanged(DownloadInfo downloadInfo) {
for(int i=0;i<observers.size();i++) {
DownloadObserver downloadObserver = observers.get(i);
downloadObserver.onDownloadStateChanged(downloadInfo);
}
} private void notifyDownloadProgressChanged(DownloadInfo downloadInfo) {
for(int i=0;i<observers.size();i++) {
DownloadObserver downloadObserver = observers.get(i);
downloadObserver.onDownloadProgressChanged(downloadInfo);
}
} }

DownloadIofo.java

import android.os.Environment;
import java.io.File;
import cn.loaderman.manager.MyDownloadManager; public class DownloadInfo { public String downloadUrl;
public String id;
public String name;
public String packageName;
public String size;
public long currentPosition;//当前下载的位置
public int currentState;//下载的状态
public String filePath;//下载存储的本地路径 public static DownloadInfo createDownloadInfoFromAppInfo(AppInfo appInfo) {
DownloadInfo downloadInfo = new DownloadInfo();
downloadInfo.id = appInfo.id;
downloadInfo.downloadUrl = appInfo.downloadUrl;
downloadInfo.name = appInfo.name;
downloadInfo.packageName = appInfo.packageName;
downloadInfo.size = appInfo.size;
downloadInfo.currentState = MyDownloadManager.STATE_NONE;
downloadInfo.currentPosition = 0;
downloadInfo.filePath = getFilePath(appInfo.name);// /sdcard/GooglePlay10/xxx.apk
return downloadInfo;
} public static String getFilePath(String name) {
File rootDir = Environment.getExternalStorageDirectory();
File appDir = new File(rootDir, "MyFile");
if(!appDir.exists()||appDir.isFile()) {
if(appDir.mkdirs()) { } else {
return null;
}
}
File apkFile = new File(appDir, name + ".apk");
return apkFile.getAbsolutePath();
} }

AppInfo.java

package cn.loaderman.bean;

import java.io.Serializable;
import java.util.ArrayList; public class AppInfo { public String des;
public String downloadUrl;
public String iconUrl;
public String id;
public String name;
public String packageName;
public String size;
public String stars;
public String author;
public String date;
public String downloadNum;
public ArrayList<SafeInfo> safe;
public ArrayList<String> screen;
public String version;
}

SafeInfo.java

public class SafeInfo {

    public String safeDes;
public String safeDesColor;
public String safeDesUrl;
public String safeUrl;
}

httpHelper.java

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.SyncBasicHttpContext; import android.util.Log; import cn.loaderman.utils.IOUtils;
import cn.loaderman.utils.StringUtils; public class HttpHelper { public static final String TAG = "HttpHelper"; //127.0.0.1---> localhost
public static final String URL = "http://127.0.0.1:8090/"; /** get请求,获取返回字符串内容 */
public static HttpResult get(String url) {
HttpGet httpGet = new HttpGet(url);
return execute(url, httpGet);
} /** post请求,获取返回字符串内容 */
public static HttpResult post(String url, byte[] bytes) {
HttpPost httpPost = new HttpPost(url);
ByteArrayEntity byteArrayEntity = new ByteArrayEntity(bytes);
httpPost.setEntity(byteArrayEntity);
return execute(url, httpPost);
} /** 下载 */
public static HttpResult download(String url) {
HttpGet httpGet = new HttpGet(url);
return execute(url, httpGet);
} /** 执行网络访问 */
private static HttpResult execute(String url, HttpRequestBase requestBase) {
boolean isHttps = url.startsWith("https://");//判断是否需要采用https
AbstractHttpClient httpClient = HttpClientFactory.create(isHttps);
HttpContext httpContext = new SyncBasicHttpContext(new BasicHttpContext());
HttpRequestRetryHandler retryHandler = httpClient.getHttpRequestRetryHandler();//获取重试机制
int retryCount = 0;
boolean retry = true;
while (retry) {
try {
HttpResponse response = httpClient.execute(requestBase, httpContext);//访问网络
if (response != null) {
return new HttpResult(response, httpClient, requestBase);
}
} catch (Exception e) {
IOException ioException = new IOException(e.getMessage());
retry = retryHandler.retryRequest(ioException, ++retryCount, httpContext);//把错误异常交给重试机制,以判断是否需要采取从事
Log.e(TAG,e.getMessage());
}
}
return null;
} /** http的返回结果的封装,可以直接从中获取返回的字符串或者流 */
public static class HttpResult {
private HttpResponse mResponse;
private InputStream mIn;
private String mStr;
private HttpClient mHttpClient;
private HttpRequestBase mRequestBase; public HttpResult(HttpResponse response, HttpClient httpClient, HttpRequestBase requestBase) {
mResponse = response;
mHttpClient = httpClient;
mRequestBase = requestBase;
} public int getCode() {
StatusLine status = mResponse.getStatusLine();
return status.getStatusCode();
} /** 从结果中获取字符串,一旦获取,会自动关流,并且把字符串保存,方便下次获取 */
public String getString() {
if (!StringUtils.isEmpty(mStr)) {
return mStr;
}
InputStream inputStream = getInputStream();
ByteArrayOutputStream out = null;
if (inputStream != null) {
try {
out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024 * 4];
int len = -1;
while ((len = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
byte[] data = out.toByteArray();
mStr = new String(data, "utf-8");
} catch (Exception e) {
Log.e(TAG,e.getMessage());
} finally {
IOUtils.close(out);
close();
}
}
return mStr;
} /** 获取流,需要使用完毕后调用close方法关闭网络连接 */
public InputStream getInputStream() {
if (mIn == null && getCode() < 300) {
HttpEntity entity = mResponse.getEntity();
try {
mIn = entity.getContent();
} catch (Exception e) {
Log.e(TAG,e.getMessage());
}
}
return mIn;
} /** 关闭网络连接 */
public void close() {
if (mRequestBase != null) {
mRequestBase.abort();
}
IOUtils.close(mIn);
if (mHttpClient != null) {
mHttpClient.getConnectionManager().closeExpiredConnections();
}
}
}
}

HttpClientFactory.java

import org.apache.http.*;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.HttpEntityWrapper;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.*;
import java.util.zip.GZIPInputStream; public class HttpClientFactory {
/** http请求最大并发连接数 */
private static final int MAX_CONNECTIONS = 10;
/** 超时时间 */
private static final int TIMEOUT = 10 * 1000;
/** 缓存大小 */
private static final int SOCKET_BUFFER_SIZE = 8 * 1024; // 8KB
/** 错误尝试次数,错误异常表请在RetryHandler添加 */
private static final int MAX_RETRIES = 5;
private static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
private static final String ENCODING_GZIP = "gzip"; public static DefaultHttpClient create(boolean isHttps) {
HttpParams params = createHttpParams();
DefaultHttpClient httpClient = null;
if (isHttps) {
// 支持http与https
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
// ThreadSafeClientConnManager线程安全管理类
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
httpClient = new DefaultHttpClient(cm, params);
} else {
httpClient = new DefaultHttpClient(params);
}
return httpClient;
} private static HttpParams createHttpParams() {
final HttpParams params = new BasicHttpParams();
// 设置是否启用旧连接检查,默认是开启的。关闭这个旧连接检查可以提高一点点性能,但是增加了I/O错误的风险(当服务端关闭连接时)。
// 开启这个选项则在每次使用老的连接之前都会检查连接是否可用,这个耗时大概在15-30ms之间
HttpConnectionParams.setStaleCheckingEnabled(params, false);
HttpConnectionParams.setConnectionTimeout(params, TIMEOUT);// 设置链接超时时间
HttpConnectionParams.setSoTimeout(params, TIMEOUT);// 设置socket超时时间
HttpConnectionParams.setSocketBufferSize(params, SOCKET_BUFFER_SIZE);// 设置缓存大小
HttpConnectionParams.setTcpNoDelay(params, true);// 是否不使用延迟发送(true为不延迟)
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); // 设置协议版本
HttpProtocolParams.setUseExpectContinue(params, true);// 设置异常处理机制
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);// 设置编码
HttpClientParams.setRedirecting(params, false);// 设置是否采用重定向 ConnManagerParams.setTimeout(params, TIMEOUT);// 设置超时
ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(MAX_CONNECTIONS));// 多线程最大连接数
ConnManagerParams.setMaxTotalConnections(params, 10); // 多线程总连接数
return params;
} /** 当服务器返回的数据是以Gzip压缩的过后的数据,填充Response返回的实体数据 (Description),则返回GZIP解压流 */
private static class InflatingEntity extends HttpEntityWrapper {
public InflatingEntity(HttpEntity wrapped) {
super(wrapped);
} @Override
public InputStream getContent() throws IOException {
return new GZIPInputStream(wrappedEntity.getContent());
} // 因为数据是压缩数据,所以实际长度无法估计,可以返回-1
@Override
public long getContentLength() {
return -1;
}
} /** 自定义的安全套接字协议的实现,目前采用默认的,未使用到 */
private static class SSLSocketFactoryEx extends SSLSocketFactory {
// 此类的实例表示安全套接字协议的实现,它充当用于安全套接字工厂或 SSLEngine 的工厂。用可选的一组密钥和信任管理器及安全随机字节源初始化此类。
SSLContext sslContext = SSLContext.getInstance("TLS"); public SSLSocketFactoryEx(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
// TrustManager负责管理做出信任决定时使用的的信任材料,也负责决定是否接受同位体提供的凭据。
// X509TrustManager此接口的实例管理使用哪一个 X509 证书来验证远端的安全套接字。决定是根据信任的证书授权、证书撤消列表、在线状态检查或其他方式做出的。
TrustManager tm = new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;// 返回受验证同位体信任的认证中心的数组。
} @Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
// 给出同位体提供的部分或完整的证书链,构建到可信任的根的证书路径,并且返回是否可以确认和信任将其用于基于验证类型的客户端 SSL 验证。
} @Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
// 给出同位体提供的部分或完整的证书链,构建到可信任的根的证书路径,并且返回是否可以确认和信任将其用于基于验证类型的服务器 SSL 验证。
}
};
sslContext.init(null, new TrustManager[]{tm}, null);
} @Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
} @Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
}

IOutils.java

import java.io.Closeable;
import java.io.IOException; import android.util.Log; public class IOUtils { public static final String TAG = "IOUtils"; /** 关闭流 */
public static boolean close(Closeable io) {
if (io != null) {
try {
io.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
return true;
}
}

UiUtils.java

package cn.loaderman.utils;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Toast; import java.util.Random; /**
* 处理和UI操作相关的工具类
*/ public class UiUtils { //获取全局Context对象
public static Context getContext() {
return MyApplication.instance.context;
} //获取主线程的Handler对象
public static Handler getMainThreadHandler() {
return MyApplication.instance.handler;
} //获取主线程的线程id
public static int getMainThreadId() {
return MyApplication.instance.mainThreadId;
} //获取字符串
public static String getString(int resId) {
return getContext().getResources().getString(resId);
} //获取字符串数组
public static String[] getStringArray(int resId) {
return getContext().getResources().getStringArray(resId);
} //获取drawable
public static Drawable getDrawable(int resId) {
return getContext().getResources().getDrawable(resId);
} public static int getColor(int resId) {
return getContext().getResources().getColor(resId);
} //产生随机的颜色值  90~230
public static int getRandomColor() {
Random random= new Random();
int red = 90 + random.nextInt(141);;
int green= 90 + random.nextInt(141);;
int blue= 90 + random.nextInt(141);;
int color = Color.rgb(red, green, blue);
return color;
}
//获取文字大小   16~25
public static int getRandomTextSize() {
Random random= new Random();
return 16+random.nextInt(10);
} //获取颜色的状态选择器
public static ColorStateList getColorStateList(int resId) {
return getContext().getResources().getColorStateList(resId);
} public static int getDimen(int resId) {
return getContext().getResources().getDimensionPixelSize(resId);
} //dip2px
public static int dip2px(int dip) {
//屏幕密度
float density = getContext().getResources().getDisplayMetrics().density;
return (int) (dip * density + 0.5f);
} //px2dip
public static int px2dip(int px) {
//屏幕密度
float density = getContext().getResources().getDisplayMetrics().density;
return (int) (px/density + 0.5f);
} public static View inflateView(int resId) {
return View.inflate(getContext(), resId, null);
} public static void toast(String msg) {
Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
}
//判断是否是在主线程
public static boolean isRunOnUiThread() {
//1、获取当前线程的id
int currentThreadId = android.os.Process.myTid();
//2、获取主线程的id
int mainThreadId = getMainThreadId();
//3、做比较
return currentThreadId == mainThreadId;
} /**
* 保证r这个任务一定是在主线程中执行
*
* Process:进程
* Thread:线程
* Runnable:任务
*
* @param r
*/
public static void runOnUiThread(Runnable r) {
if (isRunOnUiThread()) {
//主线程
//new Thread(r).start();
r.run();
} else {
//子线程
getMainThreadHandler().post(r);//将任务r丢到了主线程的消息队列
}
} //代码中创建shape标签对应的对象
public static GradientDrawable getShape(int radius,int color) {
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
gradientDrawable.setCornerRadius(radius);
gradientDrawable.setColor(color);
return gradientDrawable;
}
//代码中获取一个状态选择器 对应的类StateListDrawable
public static StateListDrawable getSelector(Drawable pressedDrawable,Drawable normalDrawable) {
StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[]{android.R.attr.state_pressed},pressedDrawable);
stateListDrawable.addState(new int[]{},normalDrawable);
return stateListDrawable;
} public static int getScreenWidth() {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
return displayMetrics.widthPixels;
} }

StringUitls.java

public class StringUtils {
/** 判断字符串是否有值,如果为null或者是空字符串或者只有空格或者为"null"字符串,则返回true,否则则返回false */
public static boolean isEmpty(String value) {
if (value != null && !"".equalsIgnoreCase(value.trim()) && !"null".equalsIgnoreCase(value.trim())) {
return false;
} else {
return true;
}
//"null"
//null }
}

MyApplication.java

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Process; import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType; import java.util.ArrayList; /**
* 1、生命周期长
* 2、单实例
* 3、onCreate方法可以简单的认为是一个应用程序的入口,onCreate是运行在主线程中
*
* 问题:onCreate这个方法只执行一次么?
*
* 注意事项:需要清单文件中注册
*/ public class MyApplication extends Application { public Context context;
public Handler handler;
public int mainThreadId; public static MyApplication instance; public AppInfo appInfo; @Override
public void onCreate() {
super.onCreate();
instance = this;
//Context 获取全局的context对象 new出一个View,加载布局文件,Toast
context = getApplicationContext(); //线程间的通信
//handler.sendMessage:发送一个消息到消息队列
//主线程有主线程的消息队列,子线程有子线程的消息队列
//到底发送到哪一个线程的消息队列,得看handler维护的是哪个线程的消息队列
//指定Handler维护的是主线程消息队列的方式:1、2、
handler = new Handler();
/*new Thread(new Runnable() {
@Override
public void run() {
Handler mHandler = new Handler(Looper.getMainLooper());
}
}).start();*/ //判断当前线程是主线程还是子线程
mainThreadId = Process.myTid(); initImageLoader(getApplicationContext());
} private ArrayList<Activity> activityArrayList = new ArrayList<>(); public void addActivity(Activity activity) {
activityArrayList.add(activity);
} public void removeActivity(Activity activity) {
activityArrayList.remove(activity);
} public static void initImageLoader(Context context) {
// This configuration tuning is custom. You can tune every option, you may tune some of them,
// or you can create default configuration by
// ImageLoaderConfiguration.createDefault(this);
// method.
ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);
config.threadPriority(Thread.NORM_PRIORITY - 2);
config.denyCacheImageMultipleSizesInMemory();
config.diskCacheFileNameGenerator(new Md5FileNameGenerator());
config.diskCacheSize(50 * 1024 * 1024); // 50 MiB
config.tasksProcessingOrder(QueueProcessingType.LIFO);
config.writeDebugLogs(); // Remove for release app
// Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(config.build());
}
}

导入org.apache.http.legacy.jar

下载的管理类MyDownloadManager的更多相关文章

  1. DownloadManager 下载管理类

    演示 简介 从Android 2.3开始新增了一个下载管理类,在SDK的文档中我们查找android.app.DownloadManager可以看到.下载管理类可以长期处理多个HTTP下载任务,客户端 ...

  2. [转]3天搞定的小型B/S内部管理类软件定制开发项目【软件开发实战10步骤详解】

    本文转自:http://www.cnblogs.com/jirigala/archive/2010/10/07/1845275.html 2010-10-07 21:39 by 通用C#系统架构, 5 ...

  3. 【Cocos2d-X开发学习笔记】第19期:动作管理类(CCActionManager)的使用

    本系列学习教程使用的是cocos2d-x-2.1.4(最新版为3.0alpha0-pre) ,PC开发环境Windows7,C++开发环境VS2010 一.动作管理类 动作管理类CCActionMan ...

  4. [Canvas]空战游戏进阶 增加己方子弹管理类

    点此下载源码,可用Chrome打开观看. 图例: 代码: <!DOCTYPE html> <html lang="utf-8"> <meta http ...

  5. [Canvas]空战游戏进阶 增加爆炸管理类

    点此下载源码,欲观看效果请用Chrome打开index.html 图例: 源码: <!DOCTYPE html> <html lang="utf-8"> & ...

  6. 线程池的管理类MyThreadPoolManager

    import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Executor; import java.ut ...

  7. 【Unity3D游戏开发】之全局管理类的几种方式 (十六)

    如何在Unity中实现全局管理类?由于Unity脚本的运行机制和面向组件编程(COP)的思想,实现起来和普通的方式略有差别. 第一种方式是使用静态类.适合存储一些全局的变量,如游戏当前关卡.玩家得分等 ...

  8. Unity协程(Coroutine)管理类——TaskManager工具分享

    博客分类: Unity3D插件学习,工具分享 源码分析   Unity协程(Coroutine)管理类——TaskManager工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处 ...

  9. FreeOnTerminate 的线程在线程管理类的Destroy释放时手工释放的问题

    这个问题折腾了我整整一天. 有一个线程管理类,集中管理所有新建的线程, 线程统一在创建时标识 FreeOnTerminate 为 True. 因为有的线程是不限次循环的,所以在管理类最后 Destro ...

随机推荐

  1. ERP人员组织岗位权限菜单关系视图

  2. ceph问题汇总

    1. [ceph_deploy][ERROR ]RuntimeError: Failed to execute command: yum -y install epel-release 解决方案 进入 ...

  3. idea运行web项目乱码

    windows下idea中web项目乱码,主要原因是服务器端乱码(执行webservlet的时候,编码格式改变),导致客户端的编码格式与webservlet传递过的编码格式不一致. 前端网页的编码,通 ...

  4. 提取全局应用程序集中的dll

    如何提取全局应用程序集中的dll GAC路径:C:\WINDOWS\assembly 在资源管理器中打开这个路径看到的东西不能复制,右键中也只有 “卸载” 和 “属性” 两个菜单. 在命令提示符下切换 ...

  5. Matlab复习

    Matlab是刚好两年前(大三)接触的,那时一些课程(遥感图像处理.计量地理学......)要涉及简单的数学建模的问题.Matlab在那些资深的开发者看来可能是一门有点边缘化的东西,虽然也能做开发,能 ...

  6. Mysql: 开启慢查询日志[ERROR] unknown variable 'log-slow-queries'处理办法

    参考: http://www.dataguru.cn/thread-305503-1-1.html # slow query log qjp 20160921 # mysql5.6版本以上,取消了参数 ...

  7. Python基础-day05

    高级变量类型 目标 列表 元组 字典 字符串 公共方法 变量高级 知识点回顾 Python 中数据类型可以分为 数字型 和 非数字型 数字型 整型 (int) 浮点型(float) 布尔型(bool) ...

  8. testNG之测试报告

    原文:https://www.cnblogs.com/yuan-yuan/p/4503524.html 测试报告 执行完测试用例之后,会在项目的test-output(默认目录)下生成测试报告 打开i ...

  9. k8s-for批量拉取国内镜像并做tag标签

    kubeadm config images list  ##查看所需镜像 如果是1.15 或者是其他就需要改改 又或者是下面的国内的镜像地址不能用了 百度完改改就ok   #!/bin/bash im ...

  10. Mycat常见问题与解决方案

    转载于:https://www.cnblogs.com/jpfss/p/8194111.html 1 Mycat目前有哪些功能与特性? 答:• 支持 SQL 92标准• 支持Mysql集群,可以作为P ...