为了减少APK文件的大小,我想从我的项目中删除drawables(图像和XML文件),并在第一个应用程序启动时从我的服务器下载正确的文件。
问题是如何在我的代码中加载和使用下载的drawable?
这是我在一些研究后发现的:
BitmapDrawable
。NinePatchDrawable
。但我仍然不知道如何加载和使用引用其他drawable的XML drawable,如下所示:
<layer-list>
<item>
<bitmap android:src="@drawable/other_drawable" />
</item>
</layer-list>
对于减少APK文件大小的这个或其他有效想法的任何想法将不胜感激。
注意:
更新
经过一些更多的研究,我似乎可以通过使用引用的drawables的自定义属性和Drawable
的子类而不是本地BitmapDrawable
来修改它们之后加载/使用下载的XML drawables。所以上面的XML drawable示例将变成这样:
<layer-list xmlns:custom="http://schemas.android.com/apk/res-auto">
<item>
<custom-bitmap custom:ref="other_drawable" />
</item>
</layer-list>
虽然,这不是一个非常简单的解决方案,但我不确定它比手动操作更好。
参考文献:
答案 0 :(得分:2)
XML文件和drawable只是为了帮助开发人员,这些不是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中返回此布局!
对于drawable,在drawable中包含非常重要的内容,并通过HTTP Calls下载其他内容。
希望它有所帮助。
答案 1 :(得分:2)
首先,如果您的应用程序具有强烈的ui交互,那么该大小也不会太糟糕。此外,在某些时刻用户将需要下载那个drawables,为什么不从谷歌Playstore安装?无论如何,如果你真的想这样做,你可以做到以下几点:
对于布局中的引用,您需要从每个具有对drawable引用的窗口小部件进行连接并实现自己的标记。例如,如果您的旧布局如下所示:
<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
,您可以查看以下链接:
你可以做一些技巧,比如有一个两级缓存,第一个有内存缓存,第二个有磁盘缓存。已经存在的库可以执行这样的操作,但是您需要自定义标记,您可以修改这些库或在类中使用缓存库,如上所示。
对于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
,mySecondFrame
和myThirdFrame
是否已在缓存中。如果没有,则下载并添加它们。
希望这有帮助,但如果我是你,我会保持这个大小,个人不是那么多,我已经开发了一个有很多动画和ui功能的tumblr客户端,而apk大小约为15 MiB
答案 2 :(得分:1)
我怀疑你的drawable是否这么多(20MB)在这里我的意思是drawable是仅xml文件。 因为这些以后无法下载,您是否正确优化了可重用性代码?
但你可以免费使用图像/原始音频文件或类似的东西
注意:如果您正在寻找downloadable xml drawables
,那么回答是否是不可能它必须带有apk,您也可以按照以下方式进行操作优化
正如您的问题所述,如何使用Downloaded drawable代码
所以答案是你不能使用xml drawable但是你可以用图像做这些事情
并且有明确的方法可以从文件设置drawable
或从文件
Bitmap
答案 3 :(得分:0)
根据您的要求,您无法在运行时更改xml drawable。
其他如果您仍然需要此功能,可以在应用程序的启动画面下载它,并按照建议使用BitmapDrawable将其设置为运行时。
但是根据我的观点,这不是正确使用它的方式,因为当您创建活动时,您的视图已经在setContentView(layoutID)上呈现。因此,当您调用活动时,它将显示没有图像的空白视图。
从其他资源我已经读过,你不能在运行时更改像drawable,raw,strings这样的资源文件,因为它的id不能在运行时创建。
答案 4 :(得分:0)
您可以使用扩展文件(请参阅http://developer.android.com/google/play/expansion-files.html)并使用jobb工具(http://developer.android.com/tools/help/jobb.html)将资源移到那里。
只要尚未下载扩展文件,您仍然需要处理不可用的资源。