Android加载大图不OOM
首先,我们试着往sdcard里放一张400k的图片,但是分辨率是2560*1600
布局简单
<?xml version="1.0" encoding="utf-8"?> <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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.dell.myapplication.MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="loading ima" android:id="@+id/button" android:layout_alignParentTop="true" android:layout_centerHorizontal="true"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView" android:layout_below="@+id/button" android:layout_centerHorizontal="true" android:layout_marginTop="213dp"/> </RelativeLayout>
MainActivity
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends AppCompatActivity { Button mbutton; ImageView mImageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mbutton= (Button) findViewById(R.id.button); mImageView= (ImageView) findViewById(R.id.imageView); mbutton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Bitmap bitmap= BitmapFactory.decodeFile("/storage/sdcard/test.JPG");//将图片转换为bitmap mImageView.setImageBitmap(bitmap); } }); } }
很简单,设置点击按钮开始加载图片
结果:
报的错误:
08-16 21:17:08.410 2947-2947/com.example.dell.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:530)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:303)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:329)
at com.example.dell.myapplication.MainActivity$1.onClick(MainActivity.java:23)
at android.view.View.performClick(View.java:4240)
at android.view.View$PerformClick.run(View.java:17721)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
这时候,你可能会想,天呐,我的图片明明只有400Kb啊,怎么可能会OutOfMemoryError!!是我的虚拟机太腊鸡了吗?
其实不是这样
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.WindowManager; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends AppCompatActivity { Button mbutton; ImageView mImageView; int screenWidth; int screenHeight; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); WindowManager wm= (WindowManager) getSystemService(WINDOW_SERVICE); screenWidth= wm.getDefaultDisplay().getWidth(); screenHeight=wm.getDefaultDisplay().getHeight(); System.out.print("手机宽"+screenWidth+"手机高"+screenHeight); mbutton= (Button) findViewById(R.id.button); mImageView= (ImageView) findViewById(R.id.imageView); mbutton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //创建bitmap工厂的配置参数 BitmapFactory.Options options=new BitmapFactory.Options(); //返回null,不去真正解析位图,只是得到宽高等信息 options.inJustDecodeBounds=true; BitmapFactory.decodeFile("/storage/sdcard/test.JPG",options); int imgWidth=options.outWidth; int imgHeight=options.outHeight; System.out.print("图片宽"+imgWidth+"图片高"+imgHeight); // 计算缩放比 int scale=1; int scalex=imgWidth/screenWidth; int scaley=imgHeight/screenHeight; scale=scalex>scaley?scalex:scaley; //按照缩放比显示图片 options.inSampleSize=scale; //开始真正解析位图 options.inJustDecodeBounds=false; Bitmap bitmap=BitmapFactory.decodeFile("/storage/sdcard/test.JPG",options); mImageView.setImageBitmap(bitmap); } }); } }
打印结果:
08-16 22:03:22.542 9790-9790/com.example.dell.myapplication I/System.out: 手机宽320手机高480
08-16 22:03:38.432 9790-9790/com.example.dell.myapplication I/System.out: 图片宽2560图片高1600