アーカイブZipおよび7zを使用する

モバイル開発では、インターネットなしで動作するアプリケーションを作成する必要があります。 たとえば、厳しいフィールド条件で使用される辞書や参考書。 次に、アプリケーションを機能させるために、データアーカイブを一度ダウンロードして保存する必要があります。 ネットワークにクエリを実行してこれを行うことができますが、アプリケーション内でデータアーカイブをアーカイブすることもできます。



Google Playの要件に従って、アプリケーションのapk-ファイルは50 MB以下である必要があります 。2ギガバイトの.obbアドオンファイルを2つ添付することもできます 。 メカニズムはシンプルですが、操作中は複雑なので、50 MB以内に維持しておくのが最善です。 これで、 Zip7zの 2つのアーカイブ形式全体が役立ちます。



既製のテストアプリケーションZipExampleの例に関する彼らの仕事を見てみましょう。



テスト用に、 sqliteデータベースtest_data.dbが作成されました。 これには、android_metadataの2つのテーブルが含まれています-伝統的に、100万行のmy_test_dataです。







結果のファイルサイズは198 MBです。



2つのアーカイブtest_data.zip(10.1 MB)およびtest_data.7z(3.05 MB)を作成します。



ご覧のとおり、 sqliteデータベースファイルは非常によく圧縮されています。 経験から言えば、ベースの構造が単純であるほど、圧縮率が高くなると言えます。 これらのファイルは両方とも資産フォルダーにあり、操作中に解凍されます。







プログラムの外観は、テキストと2つのボタンがあるウィンドウです。







zipアーカイブを解凍する方法は次のとおりです。

public void onUnzipZip(View v) throws IOException { SimpleDateFormat sdf = new SimpleDateFormat(" HH:mm:ss.SSS"); String currentDateandTime = sdf.format(new Date()); String log = mTVLog.getText().toString() + "\nStart unzip zip" + currentDateandTime; mTVLog.setText(log); InputStream is = getAssets().open("test_data.zip"); File db_path = getDatabasePath("zip.db"); if (!db_path.exists()) db_path.getParentFile().mkdirs(); OutputStream os = new FileOutputStream(db_path); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(is)); ZipEntry ze; while ((ze = zis.getNextEntry()) != null) { byte[] buffer = new byte[1024]; int count; while ((count = zis.read(buffer)) > -1) { os.write(buffer, 0, count); } os.close(); zis.closeEntry(); } zis.close(); is.close(); currentDateandTime = sdf.format(new Date()); log = mTVLog.getText().toString() + "\nEnd unzip zip" + currentDateandTime; mTVLog.setText(log); }
      
      





ここで展開するクラスはZipInputStreamで、 java.util.zipパッケージに含まれておりそのクラスは標準のAndroid SDKに含まれているため、そのまま使用できます。 個別にアップロードする必要はありません。



7zアーカイブを解凍する方法は次のとおりです。



 public void onUnzip7Zip(View v) throws IOException { SimpleDateFormat sdf = new SimpleDateFormat(" HH:mm:ss.SSS"); String currentDateandTime = sdf.format(new Date()); String log = mTVLog.getText().toString() + "\nStart unzip 7zip" + currentDateandTime; mTVLog.setText(log); File db_path = getDatabasePath("7zip.db"); if (!db_path.exists()) db_path.getParentFile().mkdirs(); SevenZFile sevenZFile = new SevenZFile(getAssetFile(this, "test_data.7z", "tmp")); SevenZArchiveEntry entry = sevenZFile.getNextEntry(); OutputStream os = new FileOutputStream(db_path); while (entry != null) { byte[] buffer = new byte[8192];// int count; while ((count = sevenZFile.read(buffer, 0, buffer.length)) > -1) { os.write(buffer, 0, count); } entry = sevenZFile.getNextEntry(); } sevenZFile.close(); os.close(); currentDateandTime = sdf.format(new Date()); log = mTVLog.getText().toString() + "\nEnd unzip 7zip" + currentDateandTime; mTVLog.setText(log); }
      
      





そして彼のアシスタント:



  public static File getAssetFile(Context context, String asset_name, String name) throws IOException { File cacheFile = new File(context.getCacheDir(), name); try { InputStream inputStream = context.getAssets().open(asset_name); try { FileOutputStream outputStream = new FileOutputStream(cacheFile); try { byte[] buf = new byte[1024]; int len; while ((len = inputStream.read(buf)) > 0) { outputStream.write(buf, 0, len); } } finally { outputStream.close(); } } finally { inputStream.close(); } } catch (IOException e) { throw new IOException("Could not open file" + asset_name, e); } return cacheFile; }
      
      





まず、 assertsからアーカイブファイルをコピーし、次にSevenZFileを使用して解凍します 。 パッケージorg.apache.commons.compress.archivers.sevenzにあります。 したがって、使用する前に、 build.gradleで 'org.apache.commons:commons-compress:1.8'のコンパイルを行う必要があります。

Android Stuodio自体がライブラリをダウンロードし、古くなっている場合は、更新があるかどうかを通知します。



実行中のアプリケーションの画面は次のとおりです。







アプリケーションのデバッグバージョンのサイズは6.8 MBでした。

そして、これは開梱後のデバイス内のサイズです:







質問は、キャッシュのブラックボックスに誰がいるかということです。



結論として、アーカイブの解凍には長い時間がかかるため、メイン( UI )ストリームでは実行できません。 これにより、インターフェイスがフリーズします。 これを回避するには、 AsyncTaskを使用します。 できればバックグラウンドサービスを使用できます。 ユーザーは解凍を待たずに終了することができ、エラーが発生します(ただし、 onPostExecuteメソッドに松葉杖を配置しない場合)。



コメントで建設的な批判ができればうれしいです。



All Articles