• 提高android应用的效率主要讲解listview的优化


    Adapter是listview和数据源间的中间人。
    
    当每条数据进入可见区域时,adapter的getview()会被调用,返回代表具体数据的视图。触摸滚动时,频繁调用。支持成百上千条数据。
    
    下面为显示每条数据的xml文件:
    
    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal">
    <ImageView android:id="@+id/icon"
    android:layout_width="48dip"
    android:layout_height="48dip" />
    <TextView android:id="@+id/text"
    android:layout_gravity="center_vertical"
    android:layout_width="0dip"
    android:layout_weight="1.0"
    android:layout_height="wrap_content" />
    </LinearLayout>
    
    1。最简单的方法,最慢且最不实用
    
    public View getView(int pos, View convertView,
    ViewGroup parent){
    View item = mInflater.inflate(R.layout.list_item, null);
    ((TextView) item.findViewById(R.id.text)).
    setText(DATA[pos]);
    ((ImageView) item.findViewButId(R.id.icon)).
    setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2);
    return item;
    }
    
    2。利用convertview回收视图,效率提高200%。
    
    public View getView(int pos, View convertView,
    ViewGroup parent){
    if (convertView == null) {
    convertView = mInflater.inflate(
    R.layout.list_item, null);
    }
    ((TextView) convertView.findViewById(R.id.text)).
    setText(DATA[pos]);
    ((ImageView) convertView.findViewButId(R.id.icon)).
    setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2);
    return convertView;
    }
    
    3。利用viewholder模式,效率在提高50%
    
    static class ViewHolder {
    TextView text;
    ImageView icon;
    }
    
     
    
    public View getView(int pos, View convertView, ViewGroup parent){
    ViewHolder holder;
    if (convertView == null) {
    convertView = mInflater.inflate(R.layout.list_item, null);
    holder = new ViewHolder();
    holder.text = (TextView) convertView.findViewById(
    R.id.text));
    holder.icon = (ImageView) convertView.findViewButId(
    R.id.icon));
    convertView.setTag(holder);
    } else {
    holder = (ViewHolder) convertView.getTag();
    }
    holder.text.setText(DATA[pos]);
    holder.icon.setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2);
    return convertView;
    }
    
    adapter更新效率比较:
    
    1的更新不到10 frames/second
    
    2的更新接近30 frames/second
    
    3的更新接近40 frames/second
    
    背景和图像
    
    视图背景图像总会填充整个视图区域
    
    1。图像尺寸不合适会导致自动缩放
    
    2。避免实时缩放
    
    3。最好预先缩放到视图大小
    
    originalImage = Bitmap.createScaledBitmap(
    originalImage, // 缩放图像
    view.getWidth(), // 视图宽度
    view.getHeight(), // 视图高度
    true); // 线性过滤器
    
    1的效率接近25 frames/second
    
    2的效率接近50 frames/second
    
    默认情况下, 窗口有一个不透明的背景
    
    有时可以不需要
    
        -最高层的视图是不透明的
    
        -  最高层的视图覆盖整个窗口
    
    layout_width = fill_parent
    layout_height = fill_parent
    
    更新看不见的背景是浪费时间
    
    删除窗口背景:
    
    1。修改编码
    
    public void onCreate(Bundle icicle){
    super.onCreate(icicle);
    setContentView(R.layout.mainview);
    // 删除窗口背景
    getWindow().setBackgroundDrawable(null);
    ...
    }
    
    2。修改xml
    
     
    
    首先确定你的res/values/styles.xml有
    
    <resources>
    <style name="NoBackgroundTheme" parent="android:Theme">
    <item name="android:windowBackground">@null</item>
    </style>
    </resources>
    
    然后编辑androidmainfest.xml
    
    <activity android:name="MyApplication"
    android:theme="@style/NoBackgroundTheme">
    ...
    </activity>
    
    更新请求
    
    当屏幕需要更新时,调用invalidate()方法,简单方便,但是更新了整个视图,代价太高。
    
    最好先找到无效区域,然后调用
    
    invalidate(Rect dirty);
    invalidate(int left, int top, int right, int
    bottom);
    
    视图和布局
    
    如果一个窗口包含很多视图,启动太慢,绘制时间长,用户界面反应速度很慢
    
    解决方法:
    
    1。使用textview的复合drawable减少层次
    
    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    android:drawableLeft="@drawable/icon"/>
    
    2。使用viewstuf延迟展开视图
    
        在xml文件中定义viewstuf
    
    <ViewStub android:id = "@+id/stub_import"
    android:inflatedId="@+id/panel_import"
    android:layout="@layout/progress_overlay"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"/>
    
      在需要展开视图时,
    
    findViewById(R.id.stub_import).setVisibility(View.VISIBLE);
    // 或者
    View importPanel = ((ViewStub)
    findViewById(R.id.stub_import)).inflate();
    
    3。使用<merge>合并中间视图
    
    默认情况下,布局文件的根作为一个节点,加入到父视图中,如果使用merge可以避免根节点
    
    <merge xmlns:android =
    "http://schemas.android.com/apk/res/android">
    <! -- Content -->
    </merge>
    
    4。使用ralativelayout减少层次
    
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="wrap_content">
    <ImageView android:id="@+id/icon"
    android:layout_width="48dip" android:layout_height="48dip"
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true"/>
    <TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:id="@+id/text_line1"
    android:layout_alignParentTop="true"
    android:layout_toRightOf="@id/icon"/>
    <TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:id="@+id/text_line2"
    android:layout_toRightOf="@id/icon"
    android:layout_below="@id/text_line1"/>
    <Checkbox android:id="@+id/star"
    android:layout_width="48dip" android:layout_height="48dip"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"/>
    </RelativeLayout>
    
    5.使用自定义视图
    
    class CustomView extends View {
    @Override
    protected void onDraw(Canvas canvas) {
    // 加入你的绘图编码
    }
    @Override
    protected void onMeasure(int widthMeasureSpec,
    int heightMeasureSpec) {
    // 计算视图的尺寸
    setMeasuredDimension(widthSpecSize, heightSpecSize);
    }
    }
    
    6 使用自定义布局
    
    class GridLayout extends ViewGroup {
    @Override
    protected void onLayout(boolean changed, int l, int t,
    int r, int b) {
    final int count = getChildCount();
    for (int i=0; i < count; i++) {
    final View child = getChildAt(i);
    if (child.getVisibility() != GONE) {
    // 计算子视图的位置
    child.layout(left, top, right, bottom);
    }
    }
    }
    }
    
    内存分配
    
    在性能敏感的代码里,避免创建java对象
    
    1。测量 onmeasure()
    
    2。布局onlayout()
    
    3。绘图 ondraw() dispatchdraw()
    
    4。事件处理 ontouchevent() dispatchtouchevent()
    
    5。adapter: getview() bindview()
    
    强行限制(适用调试模式)
    
    int prevLimit = -1;
    try {
    prevLimit = Debug.setAllocationLimit(0);
    // 执行不分配内存的代码
    } catch (dalvik.system.AllocationLimitError e) {
    // 如果代码分配内存, Java 虚拟机会抛出错误
    Log.e(LOGTAG, e);
    } finally {
    Debug.setAllocationLimit(prevLimit);
    }
    
    管理好对象:
    
    1。适用软引用:内存缓存的最佳选择
    
    2。适用弱引用:避免内存泄露
    
    内存缓存:
    
    private final HashMap<String, SoftReference<T>> mCache;
    public void put(String key, T value) {
    mCache.put(key, new SoftReference<T>(value));
    }
    public T get(String key, ValueBuilder builder) {
    T value = null;
    SoftReferece<T> reference = mCache.get(key);
    if (reference != null) {
    value = reference.get();
    
    
  • 相关阅读:
    POJ3468 A Simple Problem with Integers(线段树成段增减,区间求和)
    HDU1698 Just a Hook(线段树成段替换、区间求和,延迟标记的应用)
    HDU2795 Billboard(线段树基础题单节点更新区间查询)
    HDU1754 I Hate It(线段树基础题单节点更新区间查询)
    HDU5410 CRB and His Birthday(完全背包)
    HDU1166 敌兵布阵(线段树基础题单节点更新区间查询)
    cf C. Bombs
    cf B. Resort
    cf B. Color the Fence
    cf B. Little Dima and Equation
  • 原文地址:https://www.cnblogs.com/error404/p/2126682.html
Copyright © 2020-2023  润新知