下載的管理類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) {
                                //二、下載暫停
                                downloadInfo.currentState = STATE_PAUSED;
                                notifyDownloadStateChanged(downloadInfo);
                            } else {
                                //一、下載失敗
                                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.javajava

import android.os.Environment;
import java.io.File;
import cn.itcast.googleplay10.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.javaandroid

package cn.itcast.googleplay10.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.javaapache

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.itcast.googleplay10.utils.IOUtils;
import cn.itcast.googleplay10.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.itcast.googleplay10.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() {
        //一、獲取當前線程的id
        int currentThreadId = android.os.Process.myTid();
        //二、獲取主線程的id
        int mainThreadId = getMainThreadId();
        //三、作比較
        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;

/**
 * 一、生命週期長
 * 二、單實例
 * 三、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維護的是主線程消息隊列的方式:一、二、
        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併發

相關文章
相關標籤/搜索