• 下载的管理类MyDownloadManager


    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

  • 相关阅读:
    java Class的 getSuperclass与getGenericSuperclass区别
    再有人问你volatile是什么,把这篇文章也发给他
    深入理解乐观锁与悲观锁
    再有人问你Java内存模型是什么,就把这篇文章发给他
    再有人问你synchronized是什么,就把这篇文章发给他
    《成神之路-基础篇》JVM——Java内存模型(已完结)
    css
    css
    require.js
    css -border
  • 原文地址:https://www.cnblogs.com/loaderman/p/6822180.html
Copyright © 2020-2023  润新知