Android asynchronously takes the network image and handles the solution to the memory overflow problem

  • 2020-05-09 19:17:46
  • OfStack

The test environment is above Adnroid 2.1.
1.AndroidManifest.xml permission configuration:
Add Internet access rights:
 
<uses-permission android:name="android.permission.INTERNET" /> 

2. Asynchronous picture class ImageDownloadTask
 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.MalformedURLException; 
import java.net.URL; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.os.AsyncTask; 
import android.widget.ImageView; 
public class ImageDownloadTask extends AsyncTask<Object, Object, Bitmap> { 
private ImageView imageView = null; 
/*** 
*  Here we get the resolution of the phone  
* */ 
public void setDisplayWidth(int width) { 
_displaywidth = width; 
} 
public int getDisplayWidth() { 
return _displaywidth; 
} 
public void setDisplayHeight(int height) { 
_displayheight = height; 
} 
public int getDisplayHeight() { 
return _displayheight; 
} 
public int getDisplayPixels() { 
return _displaypixels; 
} 
private int _displaywidth = 480; 
private int _displayheight = 800; 
private int _displaypixels = _displaywidth * _displayheight; 
@Override 
protected Bitmap doInBackground(Object... params) { 
// TODO Auto-generated method stub 
Bitmap bmp = null; 
imageView = (ImageView) params[1]; 
try { 
String url = (String) params[0]; 
bmp = getBitmap(url, _displaypixels,true); 
} catch (Exception e) { 
return null; 
} 
return bmp; 
} 
protected void onPostExecute(Bitmap result) { 
if (imageView != null&&result!=null) { 
imageView.setImageBitmap(result); 
if (null != result && result.isRecycled() == false) 
System.gc(); 
} 
} 
/** 
*  through URL Get online pictures. Such as :http://www.xxxxxx.com/xx.jpg 
* */ 
public Bitmap getBitmap(String url, int displaypixels, Boolean isBig) throws MalformedURLException, IOException { 
Bitmap bmp = null; 
BitmapFactory.Options opts = new BitmapFactory.Options(); 
InputStream stream = new URL(url).openStream(); 
byte[] bytes = getBytes(stream); 
// this 3 Sentence is to deal with image overflow begin(  If you don't need to handle the overflow directly  opts.inSampleSize=1;) 
opts.inJustDecodeBounds = true; 
BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opts); 
opts.inSampleSize = computeSampleSize(opts, -1, displaypixels); 
//end 
opts.inJustDecodeBounds = false; 
bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opts); 
return bmp; 
} 
/** 
*  Data flow into btyle[] An array of  
* */ 
private byte[] getBytes(InputStream is) { 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
byte[] b = new byte[2048]; 
int len = 0; 
try { 
while ((len = is.read(b, 0, 2048)) != -1) { 
baos.write(b, 0, len); 
baos.flush(); 
} 
} catch (IOException e) { 
e.printStackTrace(); 
} 
byte[] bytes = baos.toByteArray(); 
return bytes; 
} 
/**** 
*  Processing images bitmap size exceeds VM budget  ( Out Of Memory  Out of memory)  
*/ 
private int computeSampleSize(BitmapFactory.Options options, 
int minSideLength, int maxNumOfPixels) { 
int initialSize = computeInitialSampleSize(options, minSideLength, 
maxNumOfPixels); 
int roundedSize; 
if (initialSize <= 8) { 
roundedSize = 1; 
while (roundedSize < initialSize) { 
roundedSize <<= 1; 
} 
} else { 
roundedSize = (initialSize + 7) / 8 * 8; 
} 
return roundedSize; 
} 
private int computeInitialSampleSize(BitmapFactory.Options options, 
int minSideLength, int maxNumOfPixels) { 
double w = options.outWidth; 
double h = options.outHeight; 
int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math 
.sqrt(w * h / maxNumOfPixels)); 
int upperBound = (minSideLength == -1) ? 128 : (int) Math.min( 
Math.floor(w / minSideLength), Math.floor(h / minSideLength)); 
if (upperBound < lowerBound) { 
return lowerBound; 
} 
if ((maxNumOfPixels == -1) && (minSideLength == -1)) { 
return 1; 
} else if (minSideLength == -1) { 
return lowerBound; 
} else { 
return upperBound; 
} 
} 
} 

3. Test call code:
 
@Override 
public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.main); 
ImageDownloadTask imgtask =new ImageDownloadTask(); 
/** Here is the resolution of the phone screen for processing   The picture   Overflow problem. begin*/ 
DisplayMetrics dm = new DisplayMetrics(); 
getWindowManager().getDefaultDisplay().getMetrics(dm); 
imgtask.setDisplayWidth(dm.widthPixels); 
imgtask.setDisplayHeight(dm.heightPixels); 
//end 
ImageView imageView_test= (ImageView)findViewById(R.id.imageView_test); 
imgtask.execute("http://pic.qukantu.com/big/7515/201201031116491.jpg",imageView_test); 
} 

4. Summary:
Mainly through extends AsyncTask < Object, Object, Bitmap > To implement asynchronous.
Picture Out Of Memory memory overflow this 1 block operation, in the practical application should consider calmly extraction. I put it in here for convenience. Overflow processing is essentially getting the device resolution and compressing the image.

Related articles: