Practical Practice of android H5 Local Cache Load Optimization

  • 2021-12-12 05:33:54
  • OfStack

In the last week of 2020, I am preparing to go home for the New Year by fishing, but I must not know that the "shocking conspiracy" has been brewing in the leadership. On the vertical day, the team leader came to me with a strange smile:

Team leader: "It's almost the New Year. You have a long way to go home. Do you want to take two days off?"

I: "Team leader, you are really my bosom friend, think about what I think, think about what I think, you say so, I am impolite, then I will ask for two days."

Team leader: "OK, it's no problem to ask for leave. I take good care of my brothers!!" (At that moment, a warm current passed by, and he had already forgotten his "squeezing" of me in this year)

"But I have one more thing to tell you. You have a need to complete before going home."

Me: "what???,,,, TMD......"

Team leader: "The demand is like this: Recently, the customer responded that HTML is a bit slow to load, and it needs to be optimized. It is best to drive in seconds,,,, come on, I believe you".

Me: "Not this H5, load slow that your front-end reason ah, you look for me... I..." (The team leader has gone away)

With a heavy heart, I started to study optimization, and started to make a fuss about webView layer, opening cache and preloading, and the effect of one operation was negligible.

Then start to hit the front-end file attention, 1 like the local Html file loading speed than through Url loading speed will be much faster. So I went to the front end and asked for a local file to be loaded locally in the project. Sure enough, the speed is swishing. At this time, embarrassing things happen. The front-end functions are frequently updated. If it is not H5 updated in the project, I have to upgrade the version. Not to mention that I have to be exhausted, it is estimated that this plan mentioned the team leader, and he has to bring a knife to see him. Therefore, in a different way, HTMl files will be downloaded through the interface and stored locally in the mobile phone, so that webView can load the local files of the mobile phone. 1 arc eerie smile spread on the face.

Hands-on: 1. Stealing lazy, using filedownloader to download Html compressed files


  implementation 'com.liulishuo.filedownloader:library:1.7.7'
  

Encapsulate the download tool class:


public class FileDownloadUtils {
public static FileDownloadUtils instance = null;

public FileDownloadUtils() {
}

public static FileDownloadUtils getInstance() {
  if (null == instance) {
    instance = new FileDownloadUtils();
  }
  return instance;
}

/**
 *  Single task download 
 *
 * @param downLoadUri  File download network address 
 * @param destinationUri  Absolute storage path for downloaded files 
 */
public void startDownLoadFileSingle(String downLoadUri, String destinationUri,FileDownLoaderCallBack callBack) {
  
  FileDownloader.getImpl().create(downLoadUri).setPath(destinationUri).setListener(fileDownloadListener(callBack)).start();
}

//  Download method 
private FileDownloadListener fileDownloadListener(final FileDownLoaderCallBack callBack) {
  return new FileDownloadListener() {
    @Override
    protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
      // Waiting, already in the download queue 
    }

    @Override
    protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
      // Download progress callback 
      if (callBack != null){
        callBack.downLoadProgress(task,soFarBytes,totalBytes);
      }

    }

    @Override
    protected void completed(BaseDownloadTask task) {
      // Complete the entire download process 
      if (callBack != null){
        callBack.downLoadCompleted(task);
      }
    }

    @Override
    protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
      // Pause download 
    }

    @Override
    protected void error(BaseDownloadTask task, Throwable e) {
      // Download error 
      if (callBack != null){
        callBack.downLoadError(task,e);
      }
    }

    @Override
    protected void warn(BaseDownloadTask task) {
      // In the download queue ( Waiting / Downloading ) A task with the same download connection and the same storage path already exists 
    }
  };
}

  public interface FileDownLoaderCallBack {
  // Is the file downloaded 
  void downLoadCompleted(BaseDownloadTask task);

  // Does the file download fail 
  void downLoadError(BaseDownloadTask task, Throwable e);

  // File download progress 
  void downLoadProgress(BaseDownloadTask task, int soFarBytes, int totalBytes);
 }
}
 

Unzip the Zip file


public class ZipUtils {
  public static final String TAG = "ZIP";

  public ZipUtils() {

   }

/**
 *  Decompression zip To the specified path 
 *
 * @param zipFileString ZIP Name of 
 * @param outPathString  To extract the path 
 * @throws Exception
 */
public static void UnZipFolder(String zipFileString, String outPathString) throws Exception {
  ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFileString));
  ZipEntry zipEntry;
  String szName = "";
  while ((zipEntry = inZip.getNextEntry()) != null) {
    szName = zipEntry.getName();
    if (zipEntry.isDirectory()) {
      
      szName = szName.substring(0, szName.length() - 1);
      File folder = new File(outPathString + File.separator + szName);
      folder.mkdirs();
    } else {
      Log.e(TAG, outPathString + File.separator + szName);
      File file = new File(outPathString + File.separator + szName);
      if (!file.exists()) {
        Log.e(TAG, "Create the file:" + outPathString + File.separator + szName);
        file.getParentFile().mkdirs();
        file.createNewFile();
      }
      //  Get the output stream of the file 
      FileOutputStream out = new FileOutputStream(file);
      int len;
      byte[] buffer = new byte[1024];
      //  Read bytes to buffer 
      while ((len = inZip.read(buffer)) != -1) {
        //  From the buffer ( 0 ) Position writes (bytes) bytes 
        out.write(buffer, 0, len);
        out.flush();
      }
      out.close();
    }
  }
  inZip.close();
}

public static void UnZipFolder(String zipFileString, String outPathString, String szName) throws Exception {
  ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFileString));
  ZipEntry zipEntry;
  while ((zipEntry = inZip.getNextEntry()) != null) {
    //szName = zipEntry.getName();
    if (zipEntry.isDirectory()) {
      // Gets the folder name of the part 
      szName = szName.substring(0, szName.length() - 1);
      File folder = new File(outPathString + File.separator + szName);
      folder.mkdirs();
    } else {
      Log.e(TAG, outPathString + File.separator + szName);
      File file = new File(outPathString + File.separator + szName);
      if (!file.exists()) {
        Log.e(TAG, "Create the file:" + outPathString + File.separator + szName);
        file.getParentFile().mkdirs();
        file.createNewFile();
      }
      //  Get the output stream of the file 
      FileOutputStream out = new FileOutputStream(file);
      int len;
      byte[] buffer = new byte[1024];
      //  Read bytes to buffer 
      while ((len = inZip.read(buffer)) != -1) {
        //  From the buffer ( 0 ) Position writes (bytes) bytes 
        out.write(buffer, 0, len);
        out.flush();
      }
      out.close();
    }
  }
  inZip.close();
}

/**
 *  Compressed Files and Folders 
 *
 * @param srcFileString  Files or folders to compress 
 * @param zipFileString  Decompressed completed Zip Path 
 * @throws Exception
 */
public static void ZipFolder(String srcFileString, String zipFileString) throws Exception {
  // Create ZIP
  ZipOutputStream outZip = new ZipOutputStream(new FileOutputStream(zipFileString));
  // Create a file 
  File file = new File(srcFileString);
  // Compression 
 // LogUtils.LOGE("---->"+file.getParent()+"==="+file.getAbsolutePath());
  ZipFiles(file.getParent()+ File.separator, file.getName(), outZip);
  // Complete and close 
  outZip.finish();
  outZip.close();
}

/**
 *  Zip file 
 *
 * @param folderString
 * @param fileString
 * @param zipOutputSteam
 * @throws Exception
 */
private static void ZipFiles(String folderString, String fileString, ZipOutputStream zipOutputSteam) throws Exception {
  // LogUtils.LOGE("folderString:" + folderString + "\n" +"fileString:" + fileString + "\n==========================");
  if (zipOutputSteam == null)
    return;
  File file = new File(folderString + fileString);
  if (file.isFile()) {
    ZipEntry zipEntry = new ZipEntry(fileString);
    FileInputStream inputStream = new FileInputStream(file);
    zipOutputSteam.putNextEntry(zipEntry);
    int len;
    byte[] buffer = new byte[4096];
    while ((len = inputStream.read(buffer)) != -1) {
      zipOutputSteam.write(buffer, 0, len);
    }
    zipOutputSteam.closeEntry();
  } else {
    // Folder 
    String fileList[] = file.list();
    // No subfiles and compression 
    if (fileList.length <= 0) {
      ZipEntry zipEntry = new ZipEntry(fileString + File.separator);
      zipOutputSteam.putNextEntry(zipEntry);
      zipOutputSteam.closeEntry();
    }
    // Subfiles and recursion 
    for (int i = 0; i < fileList.length; i++) {
      ZipFiles(folderString+fileString+"/", fileList[i], zipOutputSteam);
    }
  }
}

/**
 *  Return zip File input stream of 
 *
 * @param zipFileString zip Name of 
 * @param fileString  ZIP File name of 
 * @return InputStream
 * @throws Exception
 */
public static InputStream UpZip(String zipFileString, String fileString) throws Exception {
  ZipFile zipFile = new ZipFile(zipFileString);
  ZipEntry zipEntry = zipFile.getEntry(fileString);
  return zipFile.getInputStream(zipEntry);
}

/**
 *  Return ZIP List of files (files and folders) in 
 *
 * @param zipFileString ZIP Name of 
 * @param bContainFolder  Whether to include folders 
 * @param bContainFile   Whether to include files 
 * @return
 * @throws Exception
 */
public static List<File> GetFileList(String zipFileString, boolean bContainFolder, boolean bContainFile) throws Exception {
  List<File> fileList = new ArrayList<File>();
  ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFileString));
  ZipEntry zipEntry;
  String szName = "";
  while ((zipEntry = inZip.getNextEntry()) != null) {
    szName = zipEntry.getName();
    if (zipEntry.isDirectory()) {
      //  Gets the folder name of the part 
      szName = szName.substring(0, szName.length() - 1);
      File folder = new File(szName);
      if (bContainFolder) {
        fileList.add(folder);
      }
    } else {
      File file = new File(szName);
      if (bContainFile) {
        fileList.add(file);
      }
    }
  }
  inZip.close();
  return fileList;
}
}

Download:


    File file = new File(Constants.saveH5FilePath);
    if (file.exists()) {
      file.delete();
    }
    // Start downloading ZIP Compressed package 
    FileDownloadUtils.getInstance().startDownLoadFileSingle(bean.getUrl(), Constants.saveH5FilePath,
        new FileDownloadUtils.FileDownLoaderCallBack() {
          @Override
          public void downLoadCompleted(BaseDownloadTask task) {
            try {
              // Decompression ZIP Compressed package 
              ZipUtils.UnZipFolder(Constants.saveH5FilePath, Constants.unH5ZipPath);
              PreferencesUtil.getInstance().saveParam("H5VersionName", H5VersionName);

            } catch (Exception e) {
              e.printStackTrace();
            }

          }

          @Override
          public void downLoadError(BaseDownloadTask task, Throwable e) {
          }

          @Override
          public void downLoadProgress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
          }
        });

webView Load:


 mWebSe.loadUrl("file:"+ Constants.unH5ZipPath+"/index.html");

At this point, quiet inside, go home and search. . . .

The above is android H5 local cache load optimization of actual combat details, more information about android H5 local cache load optimization please pay attention to other related articles on this site!


Related articles: