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