当前正在开发一个微型应用程序,其目标是再现Android图库,但我的应用程序无法正常工作。
事实上,由于只能使用画布而没有使用任何布局的权利,我按照不同的步骤进行操作,现在我将向您解释这些步骤,以说明问题:
1-我的主要活动是运行两个对象,即两个个人类的“ Scan”对象和“ GalleryView”对象
2-扫描对象使用功能检索图库中图像的所有路径。
3-MainActivity恢复此数组列表,并将其传递给我的galleryview的生成器。
4-画廊视图知道要显示的元素数量(等于扫描返回的字符串arraylist的大小),并构建每个图像的位图以便显示它们
那就是问题所在。确实,我的手机上一共显示了约480张图像,所以我浏览GalleryView.java路径列表的位置是一个问题,因为它使应用程序崩溃。
如果我决定只绘制第一张图像的480倍,那么它将起作用。
所以我想知道如何优化此行为以避免崩溃和内存过载。
我的老师建议我们使用BitmapDrawable代替Bitmap,但我不知道如何实现。
您将在我的应用程序的所有类下找到+大致解释渲染步骤的图
MainActivity.java
public class MainActivity extends AppCompatActivity {
//Objet qui va nous permettre de récuperer les images de la gallerie du téléphone
ScanPictures m_scan;
//liste des chemins des images de la gallerie
ArrayList<String>m_paths;
//objet qui permet d'afficher les images
GalleryView m_gallery;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//On créer l'object scanner pour récuperer les photos de la gallerie
m_scan = new ScanPictures(this.getApplicationContext());
//Boolean nous indiquant si l'application à l'autorisation d'accéder au contenu interne du téléphone
Boolean isAuthorized = this.isReadStoragePermissionGranted();
//Si on est authorisé, on scan la gallerie et on récuperer les chemins des photos
if(isAuthorized){
System.out.println("SCAN IMAGES ALREADY GRANTED");
m_paths = m_scan.getImages();
System.out.println("SCAN IMAGES ALREADY GRANTED DONE");
}
m_gallery = new GalleryView(this.getApplicationContext(),m_paths);
m_gallery.setPicturesNumber(m_paths.size());
setContentView(m_gallery);
}
public boolean isReadStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) { //le sdk est supérieur a 23, l'autorisation n'est pas donnée automatiquement
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
return true;
} else {
//L'autorisation n'est pas accordée, on la demande à l'utilisateur
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 3);
return false;
}
}
else { //les permissions sont automatiquement données en sdk < 23
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//SI l'utilisateur à donner l'autorisation, on scan les photos
if (requestCode == 3 ) {
System.out.println("SCAN IMAGES FIRST GRANTED");
this.m_scan.getImages();
System.out.println("SCAN IMAGES FIRST GRANTED DONE");
}
}
}
}
GalleryView.java
public class GalleryView extends View {
private GestureDetector mGestureDetector;
private ScaleGestureDetector mScaleGestureDetector;
private float mScale = 1;
private Bitmap resized =null;
private int numColumns, numRows, nbPict;
private int cellSize;
private ArrayList<String> m_paths;
private Context m_context;
public GalleryView(Context context, ArrayList<String> paths) {
super(context);
m_context = context;
m_paths = paths;
numColumns = 7;
mGestureDetector = new GestureDetector(context, new ZoomGesture());
mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleGesture());
}
public void setPicturesNumber(int nbPict) {
this.nbPict = nbPict;
calculateDimensions();
}
private void calculateDimensions() {
numRows = nbPict/numColumns;
cellSize = getWidth() / numColumns;
invalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
calculateDimensions();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.alterralogo);
int bitmapIndex = 0;
ArrayList<Bitmap> list = new ArrayList<>();
Bitmap bitmap = BitmapFactory.decodeFile(m_paths.get(0));
for(int i = 0 ; i< nbPict;i++){
list.add(BitmapFactory.decodeFile(m_paths.get(i))); //NOT OPTIMISED AT ALL, MAKE THE APP CRASH
}
for (int i = 0; i < numColumns; i++) {
for (int j = 0; j < numRows; j++) {
resized = Bitmap.createScaledBitmap(list.get(bitmapIndex), cellSize, cellSize, true);
canvas.drawBitmap(resized, i* cellSize, j * cellSize, null);
bitmapIndex++;
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
mScaleGestureDetector.onTouchEvent(event);
return true;
}
public class ZoomGesture extends GestureDetector.SimpleOnGestureListener {
private boolean normal = true;
@Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
}
public class ScaleGesture extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
if(numColumns !=1){
numColumns--;
calculateDimensions();
}
invalidate();
return true;
}
}
}
ScanPictures.java
public class ScanPictures {
Context m_application_context;
public ScanPictures(Context activity_context){
m_application_context = activity_context;
}
public ArrayList<String> getImages(){
ArrayList<String> paths = new ArrayList<String>(); //liste qui va contenir les chemins vers les images de la gallerie
String[] columns = { MediaStore.Images.Media.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME };
String selection = MediaStore.Images.Media.BUCKET_DISPLAY_NAME + " = ? ";
String selectionArgs[] = {"Camera"};
String orderBy = MediaStore.Images.Media.DATE_TAKEN;
//Stores all the images from the gallery in Cursor
Cursor cursor = m_application_context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, selection, selectionArgs, orderBy);
//Total number of images
int count = cursor.getCount();
//Create an array to store path to all the images
String[] arrPath = new String[count];
for (int i = 0; i < count; i++) {
cursor.moveToPosition(i);
int dataColumnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
//Store the path of the image
arrPath[i]= cursor.getString(dataColumnIndex);
paths.add(arrPath[i]);
}
System.out.println(paths);
return paths;
}
}