Android性能优化注意事项
1、Android中图片优化技巧
我们知道在移动开发中内存资源很重要,而在开发中占用系统资源较多的就是图片了。因此,我们需要对图片的获得和显示进行一些必要的优化处理。
处理步骤A:有的时候为了加快响应速度,提高用户体验,一般会先加载缩略图,然后加载显示原图。那么就要对原始的图片按照一定的比例进行缩放处理,具体可以参照Android API中的建议操作,如下所示:
BitmapFactory.Options options = new BitmapFactory.Options();
// 不返回实际的Bitmap,不为其分配内存空间,指保存一些解码边界信息,如大片的大小等信息。
options.inJustDecodeBounds = true;
// 此时返回的Bitmap为空
Bitmap bitmap = BitmapFactory.decodeFile(“../temp.png”,options);
options.inJustDecodeBounds = false;
// 计算缩放的比例
Int ratio = (int) (options.outHeight/(float)200);
If(ratio <=0) {
ratio = 1;
}
// 如果ratio=2代表为原来的1/2
options.inSampleSize = ratio;
// 加载实际图片并显示
Bitmap bitmap = BitmapFactory.decodeFile(“../temp.png”,options);
另外,如果我们需要将图片缓存到本地的话,我们可以将图片按照一定的品质进行压缩并保存,具体如下:
File file=new File("/sdcard/testpng");
try {
FileOutputStream out=new FileOutputStream(file);
if(bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)){ // 图片压缩 100代表压缩品质
out.flush();
out.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
如上所示就可以处理加载较大图片时的内存溢出问题了。
处理步骤B:
如果图片没被回收的话,我们通知回收器马上回收,如下所示:
If(bitmap.isRecycled) {
Bitmap.recycle();
System.gc();
}
2、耗电量优化
我们知道在网络连接的时候,消耗的电量是比较大的,因此就有必要来优化连接网络时所耗费的电量了。首先,判断当前网络的连接状态是否正常,如果不正常的话,我们就进制下面要执行的网络连接操作,这样可以减少不必要的电量消耗。判断网络连接情况的代码如下:
private boolean isConnected(){
ConnectivityManager mConnectivity = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
TelephonyManager mTelephony = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
// 检查网络连接,如果无网络可用,就不需要进行连网操作等
NetworkInfo info = mConnectivity.getActiveNetworkInfo();
if (info == null ||
!mConnectivity.getBackgroundDataSetting()) {
return false;
}
//判断网络连接类型,只有在3G或wifi里进行一些数据更新。
int netType = info.getType();
int netSubtype = info.getSubtype();
if (netType == ConnectivityManager.TYPE_WIFI) {
return info.isConnected();
} else if (netType == ConnectivityManager.TYPE_MOBILE
&& netSubtype == TelephonyManager.NETWORK_TYPE_UMTS
&& !mTelephony.isNetworkRoaming()) {
return info.isConnected();
} else {
return false;
}
}
3、网络传输数据时的资源耗费
在网络传输数据的时候,选择合适的网络传输方式和解析方式对资源的耗费也是比较常见的,那么如何解决那?
传输方式方面:在选择网络数据传输的形式的时候,我们一般会选择那些轻量级的数据格式,比如:JSON格式数据,对于XML格式也可以,但在大量数据传输的时候,最好使用JSON,可以提高传输效率。
解析方式方面:在网络间传输的数据,获取的时候都需要我们对其进行解析,然后使用。对于网络数据的解析要求实时性较高,所以一般选择边获取数据边解析数据的方式进行,可以很好提高解析速度,例如:对于XML格式的数据,我们优先使用PULL或SAX解析方式来解析,而不是使用DOM解析,具体原因可参考上面的文章《Android中XML的解析方式》一篇。
在Android中,就我个人喜欢使用PULL解析方式,因为它轻巧易用,效率高,更重要的是使用留的方式来解析数据的。
4、传输数据压缩,减少流量流失
各位网客都知道流量的流失就是金钱的流失,所以用户使用软件的时候对于流量的流失很是重视,所以搞程序的我们就需要对于网络传输的大数据量进行压缩和解压缩来尽量减少用户流量的消耗。我们一般选择的压缩方式为GZIP压缩形式,因为大部分网站和服务端都支持这种压缩方式。具体如下:
HttpGet request = new HttpGet("http://test.example.com/gzipcontent");
HttpResponse resp = new DefaultHttpClient().execute(request);
HttpEntity entity = resp.getEntity();
InputStream compressed = entity.getContent();
InputStream rawData = new GZIPInputStream(compressed);
5、有效合理的管理Service后台服务
我们知道一般软件都有个后台服务在运行,来完成不与用户交互的工作。有些不合理的开发中,将Service启动之后,一直让其不停地运行去服务端更新数据,而不更新数据的时候就让其Sleep,这样浪费了很多不必要的资源。所以,一般会使用AlarmManager来管理和定时启动这个服务。具体如下:
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MyService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
long interval = DateUtils.MINUTE_IN_MILLIS * 30;// 每个30分钟执行一次
long firstWake = System.currentTimeMillis() + interval;
am.setRepeating(AlarmManager.RTC,firstWake, interval, pendingIntent);
6、统一管理位图资源,适时释放资源
位图占用的内存资源较大,处理不当的话就会出现内存溢出的问题,严重影响用户体验,所以我们一般会对图片统一管理,适时的进行释放。具体可参考如下(此为网友分享办法):
class ImageManager {
private WeakHashMap<Integer, WeakReference<Bitmap>> mBitmaps;
private WeakHashMap<Integer, WeakReference<Drawable》> mDrawables;
private boolean mActive = true;
public ImageManager() {
mBitmaps = new WeakHashMap<Integer, WeakReference<Bitmap>>();
mDrawables = new WeakHashMap<Integer, WeakReference<Drawable>>();
}
public Bitmap getBitmap(int resource) {
if (mActive) {
if (!mBitmaps.containsKey(resource)) {
mBitmaps.put(resource,
new WeakReference<Bitmap>(BitmapFactory.decodeResource(MainActivity.getContext().getResources(), resource)));
}
return ((WeakReference<Bitmap>)mBitmaps.get(resource)).get();
}
return null;
}
public Drawable getDrawable(int resource) {
if (mActive) {
if (!mDrawables.containsKey(resource)) {
mDrawables.put(resource, new WeakReference<Drawable>(getApplication().getResources().getDrawable(resource)));
}
return ((WeakReference<Drawable>)mDrawables.get(resource)).get();
}
return null;
}
public void recycleBitmaps() {
Iterator itr = mBitmaps.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry e = (Map.Entry)itr.next();
((WeakReference<Bitmap>) e.getValue()).get().recycle();
}
mBitmaps.clear();
}
public ImageManager setActive(boolean b) {
mActive = b;
return this;
}
public boolean isActive() {
return mActive;
}
}
对于开发中的一些优化工作是需要实际的积累经验的,所以会在以后遇到的优化处理做下总结,继续更新这篇文章,如果各位同僚有更好的更多的优化经验,可以不吝分享交流。
技术交流群:179914858