Android 정지점 다 중 스 레 드 다운로드 실현

정지점 다 중 스 레 드 다운로드 의 몇 가지 관건:①:다운로드 할 파일 크기 를 얻 은 후에 모두 몇 개의 스 레 드 에 나 누 어 줍 니 다.②:RandomAccessFile 류 를 사용 하여 읽 기와 쓰 기 를 시작 할 위 치 를 지정 할 수 있 습 니 다.③:데이터 베 이 스 는 다운로드 정 보 를 저장 하고 다음 에 계속 다운로드 할 때 데이터 베 이 스 를 추출 한 다음 에 마지막 다운로드 가 끝 난 곳 부터 시작한다.
여기 서 저 는 FinalDb 의 데이터베이스 프레임 워 크 를 사 용 했 고 메모리 에 모든 스 레 드 의 다운로드 정 보 를 저장 하여 수시로 업데이트 하고 다운로드 진 도 를 조회 합 니 다.내 가 테스트 한 것 은 바 이 두 클 라 우 드 디스크 로 파일 크기 가 50m 정도 이다.다운로드 가 끝 날 위 치 를 지정 한 네트워크 요청 의 성공 적 인 반환 코드 는 206 이 며 200 이 아 닙 니 다.
효과 그림:

스 레 드 류:스 레 드 류 는 구체 적 인 다운 로드 를 책임 지고 스 레 드 의 다운로드 정 보 는 데이터베이스 에 저 장 됩 니 다.스 레 드 가 다운 로드 를 시작 할 때 스 레 드 ID 에 따라 자신의 저장 정 보 를 조회 한 다음 지 정 된 위치 에서 파일 을 다운로드 하고 쓰기 시작 합 니 다.완료 후 현재 다운로드 결과 에 따라 현재 다운로드 상 태 를 설정 합 니 다.시간의 다운로드 진 도 는 메모리 에 만 저장 되 고 이번 다운로드 가 끝나 야 데이터베이스 에 저 장 됩 니 다.

public class DownloadThread extends Thread {
 
  /**
   *        
   */
  private FinalDb finalDb;
 
  /**
   *     :   
   */
  public static final int STATE_READY = 1;
 
  /**
   *     :   
   */
  public static final int STATE_LOADING = 2;
 
  /**
   *     :     
   */
  public static final int STATE_PAUSING = 3;
 
  /**
   *     :    
   */
  public static final int STATE_FINISH = 4;
 
  /**
   *     
   */
  public int downloadState;
 
  /**
   *   ID
   */
  private int threadID;
 
  /**
   *     URL  
   */
  private String url;
 
  /**
   *          
   */
  public RandomAccessFile file;
 
  /**
   *    
   */
  public DownloadThread(Context context, int threadID, String downloadUrl, RandomAccessFile randomAccessFile) {
    this.threadID = threadID;
    this.url = downloadUrl;
    this.file = randomAccessFile;
    finalDb = DBUtil.getFinalDb(context);
  }
 
  @Override
  public void run() {
    //            
    List<ThreadDownloadInfoBean> list = finalDb.findAllByWhere(ThreadDownloadInfoBean.class, "threadID='" + threadID + "'");
    //         
    if (list.get(0) != null) {
      MapUtil.map.put(threadID, list.get(0));
    }
    //     
    ThreadDownloadInfoBean bean = MapUtil.map.get(threadID);
    Utils.Print("bean:" + bean.toString());
    InputStream is;
    HttpURLConnection conn;
    try {
      Utils.Print("  " + threadID + "    ");
      conn = (HttpURLConnection) new URL(url).openConnection();
      conn.setConnectTimeout(5000);
      conn.setReadTimeout(5000);
      conn.setRequestMethod("GET");
      //            
      conn.setRequestProperty("Range", "bytes=" + (bean.startDownloadPosition + bean.downloadedSize) + "-" + bean.endDownloadPosition);
      conn.connect();
      if (conn.getResponseCode() == 206) {
        //      
        downloadState = STATE_LOADING;
        bean.downloadState = STATE_LOADING;
        Utils.Print("  " + threadID + "    ");
        is = conn.getInputStream();
        // 1K     
        byte[] bs = new byte[1024];
        //         
        int len;
        //          
        file.seek(bean.startDownloadPosition);
        //     ,                           ,                    ,           
        while ((len = is.read(bs)) != -1) {
          //              
          file.write(bs, 0, len);
          //               
          bean.downloadedSize += len;
          //         ,       
          if (downloadState == STATE_PAUSING) {
            Utils.Print("  " + threadID + "    ");
            break;
          }
        }
        is.close();
        file.close();
      } else {
        Utils.Print("  " + threadID + "    ");
      }
      conn.disconnect();
      //                          
      if (bean.downloadedSize >= bean.downloadTotalSize) {
        bean.downloadState = STATE_FINISH;
      } else {
        bean.downloadState = STATE_PAUSING;
      }
      //           
      finalDb.update(bean, "threadID='" + bean.threadID + "'");
    } catch (IOException e) {
      Utils.Print("  " + threadID + "IO  ");
      e.printStackTrace();
    }
  }
}
스 레 드 정보의 패 키 징 클래스:각 스 레 드 의 ID 를 저장 하고 다운로드 시작 위치,다운로드 가 끝 난 위치,다운로드 한 크기,다운로드 상태 등 을 책임 집 니 다.이 종 류 는 FinalDb 데이터베이스 로 데이터베이스 에 저장 되 며,get,set 방법 과 빈 파 라 메 트릭 을 써 야 합 니 다.

@Table(name = "ThreadInfo")
public class ThreadDownloadInfoBean {
 
  /**
   * id
   */
  public int id;
 
  /**
   *   ID
   */
  public int threadID;
 
  /**
   *             
   */
  public long startDownloadPosition;
 
  /**
   *             
   */
  public long endDownloadPosition;
 
  /**
   *             
   */
  public long downloadTotalSize;
 
  /**
   *           
   */
  public long downloadedSize;
 
  /**
   *         
   */
  public int downloadState;
 
  public ThreadDownloadInfoBean() {
 
  }
 
  public ThreadDownloadInfoBean(int downloadState, long downloadedSize, long downloadTotalSize, long endDownloadPosition, long startDownloadPosition, int threadID) {
    this.downloadState = downloadState;
    this.downloadedSize = downloadedSize;
    this.downloadTotalSize = downloadTotalSize;
    this.endDownloadPosition = endDownloadPosition;
    this.startDownloadPosition = startDownloadPosition;
    this.threadID = threadID;
  }
 
  public int getId() {
    return id;
  }
 
  public void setId(int id) {
    this.id = id;
  }
 
  public int getThreadID() {
    return threadID;
  }
 
  public void setThreadID(int threadID) {
    this.threadID = threadID;
  }
 
  public long getStartDownloadPosition() {
    return startDownloadPosition;
  }
 
  public void setStartDownloadPosition(long startDownloadPosition) {
    this.startDownloadPosition = startDownloadPosition;
  }
 
  public long getEndDownloadPosition() {
    return endDownloadPosition;
  }
 
  public void setEndDownloadPosition(long endDownloadPosition) {
    this.endDownloadPosition = endDownloadPosition;
  }
 
  public long getDownloadTotalSize() {
    return downloadTotalSize;
  }
 
  public void setDownloadTotalSize(long downloadTotalSize) {
    this.downloadTotalSize = downloadTotalSize;
  }
 
  public long getDownloadedSize() {
    return downloadedSize;
  }
 
  public void setDownloadedSize(long downloadedSize) {
    this.downloadedSize = downloadedSize;
  }
 
  public int getDownloadState() {
    return downloadState;
  }
 
  public void setDownloadState(int downloadState) {
    this.downloadState = downloadState;
  }
 
  @Override
  public String toString() {
    return "ThreadDownloadInfoBean{" +
        "id=" + id +
        ", threadID=" + threadID +
        ", startDownloadPosition=" + startDownloadPosition +
        ", endDownloadPosition=" + endDownloadPosition +
        ", downloadTotalSize=" + downloadTotalSize +
        ", downloadedSize=" + downloadedSize +
        ", downloadState=" + downloadState +
        '}';
  }
}
다운로드 도구 클래스:이 클래스 는 다운로드 파일 크기,스 레 드 다운로드 크기 할당,다운로드 스 레 드 관리

public class DownUtil {
 
  /**
   *        
   */
  public FinalDb finalDb;
 
  /**
   *     :   
   */
  public static final int STATE_READY = 1;
 
  /**
   *     :   
   */
  public static final int STATE_LOADING = 2;
 
  /**
   *     :   
   */
  public static final int STATE_PAUSING = 3;
 
  /**
   *     :    
   */
  public static final int STATE_FINISH = 4;
 
  /**
   *     
   */
  public int downloadState;
 
  /**
   * context
   */
  private Context context;
 
  /**
   *         
   */
  public long fileSize;
 
  /**
   *     
   */
  private ArrayList<DownloadThread> threadList = new ArrayList<>();
 
  /**
   *    
   */
  public DownUtil(Context context) {
    this.context = context;
    finalDb = DBUtil.getFinalDb(context);
    judgeDownState();
  }
 
  /**
   *           
   */
  public void judgeDownState() {
    //           ,      
    List<ThreadDownloadInfoBean> list = finalDb.findAll(ThreadDownloadInfoBean.class);
    if (list != null && list.size() == DownloadActivity.threadNum) {
      for (int i = 0; i < list.size(); i++) {
        MapUtil.map.put(i, list.get(i));
      }
    }
    //  SP              
    Long spFileSize = SPUtil.getInstance(context).getLong(DownloadActivity.fileName, 0L);
    long downloadedSize = getFinishedSize();
    //SP                      
    if (spFileSize == 0 || downloadedSize == 0) {
      downloadState = STATE_READY;
    } else if (downloadedSize >= spFileSize) {
      downloadState = STATE_FINISH;
    } else {
      downloadState = STATE_PAUSING;
      fileSize = spFileSize;
    }
  }
 
  /**
   *        
   */
  public void clickDownloadBtn() {
    if (downloadState == STATE_READY) {
      startDownload();
    } else if (downloadState == STATE_PAUSING) {
      continueDownload();
    }
  }
 
  /**
   *            
   */
  private void startDownload() {
    //     ,          
    new Thread() {
      @Override
      public void run() {
        try {
          HttpURLConnection conn;
          conn = (HttpURLConnection) new URL(DownloadActivity.url).openConnection();
          conn.setConnectTimeout(5000);
          conn.setReadTimeout(5000);
          conn.setRequestMethod("GET");
          conn.connect();
          if (conn.getResponseCode() == 200) {
            Utils.Print("DownUtil    ");
            //          
            fileSize = conn.getContentLength();
            //        
            String contentDisposition = new String(conn.getHeaderField("Content-Disposition").getBytes("ISO-8859-1"), "UTF-8");
            String fileName = "    " + contentDisposition.substring(contentDisposition.lastIndexOf("."), contentDisposition.lastIndexOf("\""));
            //      
            String sdCardPath = context.getExternalFilesDir(null).getPath();
            DownloadActivity.fileName = sdCardPath + "/" + fileName;
            SPUtil.getInstance(context).saveString(DownloadActivity.FILE_NAME, DownloadActivity.fileName);
            SPUtil.getInstance(context).saveLong(DownloadActivity.fileName, fileSize);
            /*
             *                             100        
             *      1  0-32,  2  33-65,  3  66-99 100,
             *                   ,                 
             */
            //         
            long threadDownSize = fileSize / DownloadActivity.threadNum;
            //           
            long leftDownSize = fileSize % DownloadActivity.threadNum;
            //        
            RandomAccessFile file = new RandomAccessFile(DownloadActivity.fileName, "rw");
            //      
            file.setLength(fileSize);
            //  
            file.close();
            for (int i = 0; i < DownloadActivity.threadNum; i++) {
              Utils.Print("    " + i);
              //             
              long startPosition = i * threadDownSize;
              //             ,                 ,    leftDownSize   
              threadDownSize = i == DownloadActivity.threadNum - 1 ? threadDownSize + leftDownSize : threadDownSize;
              //     
              ThreadDownloadInfoBean bean = new ThreadDownloadInfoBean(DownloadThread.STATE_READY, 0, threadDownSize, startPosition + threadDownSize, startPosition, i);
              finalDb.save(bean);
              RandomAccessFile threadFile = new RandomAccessFile(DownloadActivity.fileName, "rw");
              threadList.add(new DownloadThread(context, i, DownloadActivity.url, threadFile));
              threadList.get(i).start();
            }
            downloadState = STATE_LOADING;
            downloadInfoListener.connectSuccess();
          } else {
            Utils.Print("DownUtil-    ");
            downloadInfoListener.connectFail();
          }
          conn.disconnect();
        } catch (IOException e) {
          Utils.Print("DownUtil-IO  ");
          downloadInfoListener.IOException();
          e.printStackTrace();
        }
      }
    }.start();
  }
 
  /**
   *     
   */
  private void continueDownload() {
    List<ThreadDownloadInfoBean> list = finalDb.findAll(ThreadDownloadInfoBean.class);
    for (int i = 0; i < DownloadActivity.threadNum; i++) {
      //               
      if (list.get(i).downloadState != DownloadThread.STATE_FINISH) {
        Utils.Print("      " + i);
        RandomAccessFile threadFile = null;
        try {
          threadFile = new RandomAccessFile(DownloadActivity.fileName, "rw");
        } catch (FileNotFoundException e) {
          e.printStackTrace();
        }
        DownloadThread downloadThread = new DownloadThread(context, i, DownloadActivity.url, threadFile);
        threadList.add(downloadThread);
        downloadThread.start();
      }
    }
    downloadState = STATE_LOADING;
    downloadInfoListener.connectSuccess();
  }
 
  /**
   *         
   */
  public void clickPauseBtn() {
    if (downloadState == STATE_LOADING) {
      stopDownload();
    }
  }
 
  /**
   *     
   */
  private void stopDownload() {
    for (int i = 0; i < threadList.size(); i++) {
      if (threadList.get(i).downloadState == DownloadThread.STATE_LOADING) {
        threadList.get(i).downloadState = DownloadThread.STATE_PAUSING;
      }
    }
    downloadState = STATE_PAUSING;
    threadList.clear();
  }
 
  /**
   *                
   */
  public long getFinishedSize() {
    long totalSize = 0;
    for (int i = 0; i < DownloadActivity.threadNum; i++) {
      ThreadDownloadInfoBean bean = MapUtil.map.get(i);
      if (bean != null) {
        //                             
        long addSize = bean.downloadedSize > bean.downloadTotalSize ? bean.downloadTotalSize : bean.downloadedSize;
        totalSize += addSize;
      }
    }
    return totalSize;
  }
 
  /**
   *        
   */
  private DownloadInfoListener downloadInfoListener;
 
  /**
   *        
   */
  public interface DownloadInfoListener {
 
    void connectSuccess();
 
    void connectFail();
 
    void IOException();
  }
 
  /**
   *          
   */
  public void setDownloadInfoListener(DownloadInfoListener downloadInfoListener) {
    this.downloadInfoListener = downloadInfoListener;
  }
 
}
페이지 Activity:다운로드 진도 등 정 보 를 보 여주 고 조작 페이지 를 제공 합 니 다.

public class DownloadActivity extends BaseActivity {
 
  /**
   *        
   */
  private EditText et_download_url;
 
  /**
   *          
   */
  private Button btn_download_geturl;
 
  /**
   *    
   */
  private NumberProgressView np_download;
 
  /**
   *        
   */
  private Button btn_download_start;
 
  /**
   *        
   */
  private Button btn_download_pause;
 
  /**
   *        
   */
  private Button btn_download_cancel;
 
  /**
   *       
   */
  private TextView tv_download_file_info;
 
  /**
   *       
   */
  private TextView tv_download_speed;
 
  /**
   *       
   */
  private TextView tv_download_speed_info;
 
  /**
   *               
   */
  private final static int WHAT_INCREACE = 1;
 
  /**
   *        
   */
  private final static int WHAT_GET_FILENAME = 2;
 
  /**
   * downUtil    
   */
  private final static int WHAI_CONNECT_FAIL = 3;
 
  /**
   * downUtilIO  
   */
  private final static int WHAT_IO_EXCEPTION = 4;
 
  /**
   *     
   */
  private DownUtil downUtil;
 
  /**
   *          
   */
  public static final int threadNum = 5;
 
  /**
   *          SP  
   */
  public static final String FILE_NAME = "fileName";
 
  /**
   *        url  
   */
  public static String url = "";
  
  /**
   *            
   */
  public static String fileName;
 
  /**
   *                
   */
  private long lastFinishedSize;
 
  private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      switch (msg.what) {
        case WHAT_INCREACE:
          updateView();
          break;
        case WHAT_GET_FILENAME:
          tv_download_file_info.setText("    :" + fileName);
          break;
        case WHAI_CONNECT_FAIL:
          tv_download_file_info.setText("    ");
          break;
        case WHAT_IO_EXCEPTION:
          tv_download_file_info.setText("IO  ");
          break;
      }
    }
  };
 
  /**
   *     
   */
  private void updateView() {
    //             
    long currentFinishedSize = downUtil.getFinishedSize();
    //           
    StringBuilder downloadInfo = new StringBuilder();
    tv_download_speed.setText("      :" + formateSize(currentFinishedSize - lastFinishedSize) + "/s");
    //            ,    ,             ,      
    if (currentFinishedSize > lastFinishedSize) {
      lastFinishedSize = currentFinishedSize;
      downloadInfo.append("    :" + formateSize(currentFinishedSize) + "/" + formateSize(downUtil.fileSize) + "
"); for (int i = 0; i < threadNum; i++) { ThreadDownloadInfoBean bean = MapUtil.map.get(i); if (bean.downloadTotalSize != 0) { downloadInfo.append(" " + i + " :" + bean.downloadedSize * 100 / bean.downloadTotalSize + "% " + formateSize(bean.downloadedSize) + "/" + formateSize(bean.downloadTotalSize) + "
"); } } np_download.setProgress((int) (currentFinishedSize * 100 / downUtil.fileSize)); tv_download_speed_info.setText(downloadInfo); // if (currentFinishedSize >= downUtil.fileSize) { tv_download_speed.setText(" "); handler.removeMessages(WHAT_INCREACE); return; } } handler.sendEmptyMessageDelayed(WHAT_INCREACE, 1000); } /** * R.layout...... */ @Override protected int childView() { return R.layout.activity_download; } /** * , View */ @Override protected void findChildView() { et_download_url = (EditText) findViewById(R.id.et_download_url); btn_download_geturl = (Button) findViewById(R.id.btn_download_geturl); np_download = (NumberProgressView) findViewById(R.id.np_download); btn_download_start = (Button) findViewById(R.id.btn_download_start); btn_download_pause = (Button) findViewById(R.id.btn_download_pause); btn_download_cancel = (Button) findViewById(R.id.btn_download_cancel); tv_download_file_info = (TextView) findViewById(R.id.tv_download_file_info); tv_download_speed = (TextView) findViewById(R.id.tv_download_speed); tv_download_speed_info = (TextView) findViewById(R.id.tv_download_speed_info); } /** * , */ @Override protected void initChildData() { downUtil = new DownUtil(this); lastFinishedSize = downUtil.getFinishedSize(); StringBuilder downloadInfo = new StringBuilder(); fileName = SPUtil.getInstance(this).getString(FILE_NAME, null); if (fileName != null) { downloadInfo.append(" :" + fileName); if (downUtil.downloadState == DownUtil.STATE_FINISH) { np_download.setProgress(100); } else if (downUtil.downloadState == DownUtil.STATE_PAUSING) { np_download.setProgress((int) (downUtil.getFinishedSize() * 100 / downUtil.fileSize)); } tv_download_file_info.setText(downloadInfo); } } /** * , */ @Override protected View[] setChildListener() { downUtil.setDownloadInfoListener(new DownUtil.DownloadInfoListener() { @Override public void connectSuccess() { // , UI handler.sendEmptyMessage(WHAT_GET_FILENAME); handler.sendEmptyMessage(WHAT_INCREACE); } @Override public void connectFail() { handler.sendEmptyMessage(WHAI_CONNECT_FAIL); } @Override public void IOException() { handler.sendEmptyMessage(WHAT_IO_EXCEPTION); } }); return new View[]{btn_download_start, btn_download_pause, btn_download_geturl, btn_download_cancel}; } /** * View * * @param v View */ @Override protected void clickChildView(View v) { switch (v.getId()) { case R.id.btn_download_start: downUtil.clickDownloadBtn(); break; case R.id.btn_download_pause: downUtil.clickPauseBtn(); handler.removeMessages(WHAT_INCREACE); break; case R.id.btn_download_cancel: // handler.removeMessages(WHAT_INCREACE); // downUtil.clickPauseBtn(); // downUtil.downloadState = DownUtil.STATE_READY; // lastFinishedSize = 0; // tv_download_speed.setText(""); tv_download_file_info.setText(""); tv_download_speed_info.setText(""); // np_download.setProgress(0); // MapUtil.map.clear(); //sp SPUtil.getInstance(this).removeAll(); // downUtil.finalDb.deleteAll(ThreadDownloadInfoBean.class); // if (fileName != null) { File file = new File(fileName); if (file.exists()) { boolean delete = file.delete(); if (delete) { Utils.ToastS(this, " " + fileName + " "); } else { Utils.ToastS(this, " "); } } else { Utils.ToastS(this, " "); } } else { Utils.ToastS(this, " "); } break; case R.id.btn_download_geturl: String editTextUrl = et_download_url.getText().toString(); if (editTextUrl.trim().equals("")) { Utils.ToastS(this, " "); } else { url = editTextUrl; } break; } } @Override protected void onDestroy() { handler.removeCallbacksAndMessages(null); downUtil.clickPauseBtn(); super.onDestroy(); } /** * */ private String formateSize(long size) { return Formatter.formatFileSize(this, size); } }
배치

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  tools:context="com.example.testdemo.activity.DownloadActivity">
 
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
 
    <EditText
      android:id="@+id/et_download_url"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:hint="      "/>
 
    <Button
      android:id="@+id/btn_download_geturl"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="  "/>
 
  </LinearLayout>
 
  <com.example.testdemo.view.NumberProgressView
    android:id="@+id/np_download"
    android:layout_width="match_parent"
    android:layout_height="100dp">
  </com.example.testdemo.view.NumberProgressView>
 
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
 
    <Button
      android:id="@+id/btn_download_start"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="    "/>
 
    <Button
      android:id="@+id/btn_download_pause"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="    "/>
 
    <Button
      android:id="@+id/btn_download_cancel"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="    "/>
 
  </LinearLayout>
 
  <TextView
    android:id="@+id/tv_download_file_info"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
 
  <TextView
    android:id="@+id/tv_download_speed"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
 
  <TextView
    android:id="@+id/tv_download_speed_info"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
 
</LinearLayout>
Activity 의 부모 클래스 다운로드

public abstract class BaseActivity extends Activity {
 
  /**
   *      ,       
   */
  protected BaseOnClickListener onClickListener = new BaseOnClickListener();
 
  /**
   *  onCreate    ,    ,     ,       
   */
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(childView());
    findView();
    initData();
    setListener();
  }
 
  /**
   *            R.layout......
   */
  protected abstract int childView();
 
  /**
   *        ---  :https://www.buzzingandroid.com/tools/android-layout-finder/
   */
  private void findView() {
    findChildView();
  }
 
  /**
   *      
   */
  private void initData() {
    //         
    initChildData();
  }
 
  /**
   *                
   */
  private void setListener() {
    //     setChildListene()  ,    View  ,               View,    For  ,     View     
    if (setChildListener() == null || setChildListener().length == 0) {
      return;
    }
    View[] viewArray = setChildListener();
    for (View view : viewArray) {
      view.setOnClickListener(onClickListener);
    }
  }
 
  /**
   *          
   */
  protected class BaseOnClickListener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
      clickChildView(v);
    }
  }
 
  /**
   *            ,      View
   */
  protected abstract void findChildView();
 
  /**
   *            ,       
   */
  protected abstract void initChildData();
 
  /**
   *            ,        
   */
  protected abstract View[] setChildListener();
 
  /**
   *              View          
   *
   * @param v            View
   */
 
  protected abstract void clickChildView(View v);
 
}
데이터베이스 작업 클래스 가 져 오기

public class DBUtil {
 
  public static FinalDb getFinalDb(final Context context) {
 
    FinalDb finalDb = FinalDb.create(context, "REMUXING.db", false, 1, new FinalDb.DbUpdateListener() {
      @Override
      public void onUpgrade(SQLiteDatabase db, int oldVirsion, int newVirsion) {
 
      }
    });
    return finalDb;
  }
}
메모리 에 다운로드 정 보 를 저장 하 는 클래스

public class MapUtil {
  public static HashMap<Integer, ThreadDownloadInfoBean> map = new HashMap<>();
}
SP 에 저 장 된 도구 클래스

public enum SPUtil {
 
  SPUTIL;
 
  public static final String NOTIFICATIONBAR_HEIGHT = "notificationbar_height";
 
  private static SharedPreferences sp;
 
  public static SPUtil getInstance(Context context) {
 
    if (sp == null) {
      sp = context.getSharedPreferences("REMUXING", Context.MODE_PRIVATE);
    }
    return SPUTIL;
  }
 
  public void saveLong(String key, Long value) {
    sp.edit().putLong(key, value).apply();
  }
 
  public Long getLong(String key, Long defValue) {
    return sp.getLong(key, defValue);
  }
 
  public void saveString(String key, String value) {
    sp.edit().putString(key, value).apply();
  }
 
  public String getString(String key, String defValue) {
    return sp.getString(key, defValue);
  }
 
  public void removeAll() {
    sp.edit().clear().apply();
  }
 
}
도구 클래스

public class Utils {
 
  /**
   *   
   */
  public static void Print(String message) {
    Log.e("TAG", "-----   " + message + "   ------") ;
  }
 
  /**
   *    
   */
  public static void ToastS(Context context, String message) {
    Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
  }
}
진도 항목:이 건 무시 할 수 있 습 니 다.안 드 로 이 드 원생 의 코드 로 제 다른 블 로 그 를 볼 수 있 습 니 다Android 사용자 정의 View 수평 대역 디지털 백분율 진행 막대 구현
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기