刚刚从事安卓开发就遇到两大经典问题:内存溢出及适配问题
1.内存溢出就用的在网上查到的 经典的
BitmapFactory.Options opt = new BitmapFactory.Options();
is = this.getResources().openRawResource(r_id);
mImageView2.setImageBitmap(BitmapFactory.decodeStream(is,null,opt));
if(mbBitmap!=null&&!mbBitmap.isRecycled()){
mbBitmap.recycle();
mbBitmap = null;
}
尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,
因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。
因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,
decodeStream最大的秘密在于其直接调用JNI<<nativeDecodeAsset()来完成decode,
无需再使用java层的createBitmap,从而节省了java层的空间。
如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常
另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应,
使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源,
否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。
2.适配问题
1)在布局文件中不用固定的值
2)用相对布局
3)用一个大图作为背景,设置整体布局的背景颜色为图片颜色,把具体的图片和说明文字按整体布局添加到背景上,可以用margin来调节微布局,这样在不同的手机文字不会变,中间的图片会根据屏幕的大小而变化。(应用第一次使用时的帮助功能)
4)用.9图片 只适合拉伸
5)横向适配 固定短的 fill长的 margin 属性名右对齐 文字 图片分开 sp
总结:
setImageResource setImageBitmap 这两个相当于设置src 不会去适应屏幕的宽度
setBackgroundResource 设置背景 这个和屏幕有关,会拉伸或压缩图片
图片像素会影响布局
Android中的显示单位
一般HVGA代表320x480像素,这个用的比较多。
这个和设备硬件有关,一般为了支持WVGA、HVGA和QVGA推荐使用这个,不依赖像素。
主要处理字体的大小,可以根据系统的字体自适应。
除了上面三个显示单位,下面还有几个不太常用:
为了适应不同分辨率,不同的像素密度,推荐使用dip,文字使用sp。
代码如下:
// 设置窗口无标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
mInflater = getLayoutInflater();
mPageViews = new ArrayList<View>();
Class drawable = R.drawable.class;
Class string = R.string.class;
RelativeLayout linerLayout = null;
//zhanghongliu 解决大图片加载问题
BitmapFactory.Options opt = new BitmapFactory.Options();
//opt.inPreferredConfig = Bitmap.Config.RGB_565;
//opt.inPurgeable = true;
//opt.inInputShareable = true;
InputStream is = null;
for (int i = 1; i < 7; i++) {
//linerLayout = new RelativeLayout(this);
// RelativeLayout.LayoutParams paras = new
// RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
//ImageView iv = new ImageView(this);
//RelativeLayout.LayoutParams p2 = new RelativeLayout.LayoutParams(
//LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//p2.addRule(RelativeLayout.CENTER_HORIZONTAL, 1);
//p2.addRule(RelativeLayout.CENTER_VERTICAL, 1);
//iv.setLayoutParams(p2);
// iv.setScaleType(ScaleType.FIT_XY);
Field field = null;
try {
view = mInflater.inflate(R.layout.introduce_view, null);
mImageView2 = (ImageView)view.findViewById(R.id.image2);
helpbigtext = (TextView)view.findViewById(R.id.helpbigtext);
helpsmalltext = (TextView)view.findViewById(R.id.helpsmalltext);
field = drawable.getField("help" + i);
int r_id = field.getInt(field.getName());
//mImageView2.setImageResource(r_id);
//mImageView2.setBackgroundResource(r_id);
is = this.getResources().openRawResource(r_id);
mImageView2.setImageBitmap(BitmapFactory.decodeStream(is,null,opt));
field = string.getField("help"+i+"big");
helpbigtext.setText(getString(field.getInt(field.getName())));
field = string.getField("help"+i+"small");
helpsmalltext.setText(getString(field.getInt(field.getName())));
//linerLayout.addView(iv);
mPageViews.add(view);
// linerLayout.setBackgroundResource(R.color.welcomebackgorund);
} catch (Exception e) {
Log.e("ERROR", "PICTURE NOT FOUND!");
}
}
//end
// mPageViews.add(mInflater.inflate(R.layout.view_01, null));
// mPageViews.add(mInflater.inflate(R.layout.view_02, null));
View view3 = mInflater.inflate(R.layout.view_03, null);
mPageViews.add(view3);
btnBegin = (Button) view3.findViewById(R.id.btnBegin);
btnBegin.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(IntroduceActivity.this,
AreaActivity.class);
startActivity(intent);
finish();
}
});
int size = mPageViews.size();
mImageViews = new ImageView[size];
mView = mInflater.inflate(R.layout.activity_introduce, null);
mViewPager = (ViewPager) mView.findViewById(R.id.myviewpager);
mLinearLayout = (LinearLayout) mView
.findViewById(R.id.mybottomviewgroup);
for (int i = 0; i < size; i++) {
mImageView = new ImageView(IntroduceActivity.this);
mImageView.setLayoutParams(new LayoutParams(10, 10));
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(10, 0, 10, 0);
mImageView.setLayoutParams(lp);
if (i == 0) {
mImageView.setBackgroundResource(R.drawable.page_indicator_focused);
} else {
mImageView.setBackgroundResource(R.drawable.page_indicator_unfocused);
}
mImageViews[i] = mImageView;
// mImageView.setScaleType(ScaleType.FIT_XY);
// 把指示作用的远点图片加入底部的视图中
mLinearLayout.addView(mImageViews[i]);
//mLinearLayout.addView(mTextViews[i]);
}
setContentView(mView);
mViewPager.setAdapter(new MyPagerAdapter());
mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageSelected(int arg0) {
int size = mPageViews.size();
for (int i = 0; i < size; i++) {
if (i == arg0) {
mImageViews[i]
.setBackgroundResource(R.drawable.page_indicator_focused);
} else {
mImageViews[i]
.setBackgroundResource(R.drawable.page_indicator_unfocused);
}
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
});
}
class MyPagerAdapter extends PagerAdapter {
@Override
public int getCount() {
return mPageViews.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return super.getItemPosition(object);
}
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
// TODO Auto-generated method stub
((ViewPager) arg0).removeView(mPageViews.get(arg1));
}
@Override
public Object instantiateItem(View arg0, int arg1) {
// TODO Auto-generated method stub
((ViewPager) arg0).addView(mPageViews.get(arg1));
return mPageViews.get(arg1);
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
// TODO Auto-generated method stub
}
@Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
@Override
public void startUpdate(View arg0) {
// TODO Auto-generated method stub
}
@Override
public void finishUpdate(View arg0) {
// TODO Auto-generated method stub
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/helpbackground" >
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:scaleType="fitXY"
android:src="@drawable/help" />
<TextView
android:id="@+id/helpbigtext"
android:layout_width="wrap_content"
android:layout_marginTop="20dip"
android:layout_marginLeft="15dip"
android:layout_height="wrap_content"
android:text="@string/help1big"
android:textColor="@color/helpwordbig"
android:textSize="70px"/>
<TextView
android:id="@+id/helpsmalltext"
android:layout_marginLeft="15dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/help1small"
android:layout_below="@+id/helpbigtext"
android:textColor="@color/helpwordsmall"
android:textSize="36px"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/helpsmalltext"
android:layout_marginBottom="50dip"
android:layout_marginTop="50dip"
android:gravity="center_horizontal"
android:orientation="vertical" >
<ImageView
android:id="@+id/image2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
</RelativeLayout>