0

APK ファイルのサイズを小さくするために、ドローアブル (画像と XML ファイル) をプロジェクトから削除し、アプリの最初の起動時にサーバーから適切なものをダウンロードしたいと考えています。

問題は、ダウンロードしたドローアブルをコードにロードして使用する方法です。

これは、いくつかの調査の結果、私が見つけたものです。

しかし、次のように、他のドローアブルへの参照を持つ XML ドローアブルをロードして使用する方法はまだわかりません。

<layer-list>
  <item>
    <bitmap android:src="@drawable/other_drawable" />
  </item>
</layer-list>

APK ファイルのサイズを縮小するためのこのアイデアやその他の効果的なアイデアについて、ご意見をお寄せください。

ノート:

  • ドローアブルは、APK ファイル サイズ (20mb/25mb) の大部分を占めています。
  • 既に画像ファイルを圧縮しており、ProGuard を使用しています。

アップデート:

Drawableさらに調査した結果、参照されるドローアブルのカスタム属性とネイティブの代わりにのサブクラスを使用して、少し変更した後、ダウンロードした XML ドローアブルをロード/使用できるようですBitmapDrawable。したがって、上記の XML ドローアブルの例は次のようになります。

<layer-list xmlns:custom="http://schemas.android.com/apk/res-auto">
  <item>
    <custom-bitmap custom:ref="other_drawable" />
  </item>
</layer-list>

ただし、これは非常に簡単な解決策ではなく、手動で行うよりも優れているかどうかはわかりません。

参考文献:

4

5 に答える 5

2

XML ファイルとドローアブルは開発者を支援するためだけのものであり、Android でのプログラミングに不可欠な部分ではありません。サーバーからダウンロードしたい場合は、これを行うことができます。あなたがしなければならないことは、Javaファイルで手動でレイアウトやその他のものを作成することです。すなわち

RelativeLayout rl =new Relativelayout(Context);// To create Layout
Button button = new Button(Context); // Create Components Like this
button.setText("abc");// Set Properties

コンポーネントを子としてレイアウトに追加します。

rl.addView(button,new          Layoutparams(Layoutparams.WRAP_CONTENT,Layoutparams.WRAP_CONTENT));

onCreate で、このレイアウトを返します!

ドローアブルの場合、ドローアブルに非常に重要なものを含め、HTTP 呼び出しを介して他のものをダウンロードします。

それが役に立てば幸い。

于 2013-09-17T15:22:13.727 に答える
2

まず第一に、アプリケーションが UI とのやり取りが激しい場合、そのサイズはそれほど悪くありません。また、しばらくすると、ユーザーはそのドローアブルをダウンロードする必要がありますが、Google プレイストアからインストールしないのはなぜですか?. とにかく、本当にやりたい場合は、次のことができます。

レイアウトで参照するには、ドローアブルへの参照を持つすべてのウィジェットから接続し、独自のタグを実装する必要があります。たとえば、古いレイアウトが次のようになっているとします。

<RelativeLayout 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"
tools:context=".MainActivity" >

<ImageView
    android:id="@+id/someImageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:src="@drawable/somePicture" />

</RelativeLayout>

次のようになります。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.example.custom"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<com.example.custom.RemoteImageView
    android:id="@+id/someImageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    custom:remoteSrc="somePicture" />

</RelativeLayout>

にカスタム タグ定義を追加することを忘れないでくださいattrs.xml。クラスの実装では、次のようなキャッシュから画像 (存在する場合) を取得できます。

public class RemoteImageView extends ImageView {

private String remoteSrc;
private DiskLruImageCache diskCache;

public RemoteImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public RemoteImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    diskCache = new DiskLruImageCache(this, "cache", 1024 * 1024 * 30, CompressFormat.PNG, 70);
    TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
            R.styleable.RemoteImageView, 0, 0);

    try {
        remoteSrc = a.getString(R.styleable.RemoteImageView_remoteSrc);
        Bitmap cachedImage;
        if (!diskCache.containsKey(remoteSrc)) {
            //Download it from Internet and save it into the cache
            //...
            diskCache.put(remoteSrc, bitmapThatYouDownload);
        }
        cachedImage = diskCache.getBitmap(remoteSrc);
        //Use the cachedImage as the bitmap for this view.
    } finally {
        a.recycle();
    }
}

public RemoteImageView(Context context) {
    super(context);
}

}

あなたについてDiskLruImageCache確認するには、次のリンクを確認してください。

DiskLruCache

これを使用して、2 レベルのキャッシュを使用するなど、いくつかのトリックを実行できます。最初のキャッシュはメモリ キャッシュで、2 番目のキャッシュはディスク キャッシュです。このようなことを行うライブラリはすでに存在しますが、カスタムタグが必要な場合は、これらのライブラリを変更するか、上記で示したようにクラスでキャッシュライブラリを使用できます.


のようなアニメーション リストについてはAnimationDrawable、実行時にアニメーションをビルドする必要があります。たとえば、次のようにします。

AnimationDrawable animation = new AnimationDrawable();
animation.addFrame(new BitmapDrawable(getResources(),diskCache.get(myFirstFreame)), 100);
animation.addFrame(new BitmapDrawable(getResources(),diskCache.get(mySecondFrame)), 1000);
animation.addFrame(new BitmapDrawable(getResources(),diskCache.get(myThirdFrame)), 1000);
animation.setOneShot(false);

ImageView imageAnim =  (ImageView) findViewById(R.id.img);
imageAnim.setBackgroundDrawable(animation);

とがすでにキャッシュにあるmyFirstFrameかどうかを確認してください。そうでない場合は、それらをダウンロードして追加します。mySecondFramemyThirdFrame

この助けを願っていますが、私があなただったら、そのサイズを維持します.

于 2013-09-22T20:27:17.330 に答える
0

要件に従って、実行時にxmlドローアブルを変更することはできません。

この機能がまだ必要な場合は、アプリケーションのスプラッシュ画面にダウンロードして、BitmapDrawable の使用を提案したようにランタイムに設定できます。

しかし、私の意見では、これはこれを使用する正しい方法ではありません。アクティビティを作成すると、ビューはすでに setContentView(layoutID) でレンダリングされます。したがって、アクティビティを呼び出すと、画像のない空白のビューが表示されます。

そして、他のリソースから、IDは実行時に作成できないため、実行時にドローアブル、生、文字列などのリソースファイルを変更できないことを読みました。

于 2013-09-19T06:15:19.223 に答える
0

拡張ファイル ( http://developer.android.com/google/play/expansion-files.html を参照)を使用し、jobb ツール ( http://developer.android.com/tools/help ) を使用してそこにリソースを移動できます。 /jobb.html )。

ただし、拡張ファイルがダウンロードされていない限り、利用できないリソースを処理する必要があります。

于 2013-09-25T08:03:13.490 に答える