0

I am fairly new to android coding.
I have created an app that will continuously change the wallpaper of the device after certain time. Wallpapers are picked from a folder on SD card. It took me 2 months to develop this app since I have very little idea on android/java coding. Anyway, So far, I can build the apk without any problem. The app also works fine. However, it consumes a hell lot of memory on device. Like >150MB of RAM!! which is not good and android also kills the app frequently.

I am posting the code below. The change of wallpaper is done by the below code.An IntentService class.

I would be really graeatful if anyone can go through this code and tell me why is it consuming so much of resource and also, what is the possible resolution to code an app with my intended purpose?

EDIT 1: Just found out that It seems that the high memory consumption is because my app always runs in background. Is it possible to kill the app once it sets wallpaper and again run it after the delay time?

 public class ChangeWallpaper extends IntentService {
     public static volatile boolean shouldContinue = true;
     public File[] files_Chosen;
     public ArrayList<String> File_String = new ArrayList<String>();
     public ArrayList<String> File_Array = new ArrayList<String>();


     public ChangeWallpaper() {
         super(ChangeWallpaper.class.getName());
        //setIntentRedelivery(true);
     }

     @Override
     protected void onHandleIntent(Intent myintent) {
         dostuff(myintent);
     }


     private void dostuff(Intent myintent) {
         int hours_delay = myintent.getIntExtra("hours_delay", 0);
         int minutes_delay = myintent.getIntExtra("minutes_delay", 1);
         String m_chosen = myintent.getStringExtra("m_chosen");

              File_Array = myinent.getStringArrayListExtra("File_String");
         WallpaperManager myWallpaper = WallpaperManager.getInstance(getApplicationContext());

 //Caution: Infinite loop
          while (true) {
            if (!shouldContinue) {
                 stopSelf();
                 return;
             }

             for (int i = 0; i < File_Array.size(); i++) {
                 Bitmap bitmap = BitmapFactory.decodeFile(File_Array.get(i));
                 try {
                     myWallpaper.setBitmap(bitmap);


                 } catch (IOException e) {
                     e.printStackTrace();

                 }

                 try {
                    TimeUnit.HOURS.sleep(hours_delay);
                    TimeUnit.MINUTES.sleep(minutes_delay);

                     repeatStuff(m_chosen);


                 } catch (InterruptedException e) {
                     e.printStackTrace();

                 }

             }
             repeatStuff(m_chosen);

         }


     }

     public void repeatStuff(String m_chosen)
     {
         final String m_chosen1 = m_chosen;
         SimpleFileDialog FolderChooseDialog = new SimpleFileDialog(ChangeWallpaper.this, "FolderChoose",
                 new SimpleFileDialog.SimpleFileDialogListener() {
                     @Override
                     public void onChosenDir(String m_chosen1) {


                         File pathVar = new File(m_chosen1);
                         FilenameFilter imageFilter = new FilenameFilter() {
                             public boolean accept(File dir, String name) {
                                 String lowercaseName = name.toLowerCase();
                                 if (lowercaseName.endsWith(".jpg") || lowercaseName.endsWith(".jpeg")
                                         || lowercaseName.endsWith(".png")
                                         || lowercaseName.endsWith(".gif")) {
                                     return true;
                                 } else {
                                     return false;
                                 }
                             }
                         };


                         File[] files = pathVar.listFiles(imageFilter);

                         if (files.length > 1) {


                             files_Chosen = files;

                             for (int i = 0; i < files.length; i++) {
                                 File_String.add(files[i].toString());
                             }

                             File_Array = File_String;

                         }

                     }
                 });
     }

 }
Ichigo Kurosaki
  • 3,765
  • 8
  • 41
  • 56
Android_Noob
  • 487
  • 2
  • 6
  • 19
  • 1
    Your code has lots of File objects... closing them after use may be helpful – Ichigo Kurosaki Jan 25 '15 at 05:21
  • Thank you. @IchigoKurosaki... I want to try it. Searching didn't help. Could you pls tell me how do I close File Objects? – Android_Noob Jan 25 '15 at 05:28
  • Actually File don't have close method.. check this stackoverflow.com/questions/4752266/why-java-io-file-doesnt-have-a-close-method .. you can set them to null after using them. ... regarding running background service again after some time.. you can use Timertask to perodically run the service code. – Ichigo Kurosaki Jan 25 '15 at 05:34
  • If you don't want your app keep running in background, I suggest you use `AlarmManager`. – shhp Jan 25 '15 at 05:46
  • Ok.. Thanks @shhp... Any example of using AlarmManager? I searched and found that only Alarm tasks has the implementation. Can I use it to schedule any service? – Android_Noob Jan 25 '15 at 05:59
  • you can see this link [link](http://www.vogella.com/tutorials/AndroidTaskScheduling/article.html) – shhp Jan 25 '15 at 06:19
  • Do not use the file directories directly, use the MediaScanner instead. http://developer.android.com/reference/android/media/MediaScannerConnection.html – Stephan Branczyk Jan 25 '15 at 06:27

2 Answers2

0

please use scale down version of bitmap. it save a lot of precious memory this might solve your problem. following android developer guide give detail description about it.

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

mcd
  • 1,434
  • 15
  • 31
  • Just tried it out. Doesn't help much. It seems that the memory consumption is because my app always runs in background. Is it possible to kill the app once it sets wallpaper and again run it after the delay time? – Android_Noob Jan 25 '15 at 05:04
  • i think it is memory leak issue you have to see your heap memory usage. https://developer.android.com/tools/debugging/debugging-memory.html – mcd Jan 25 '15 at 05:32
0

Try clearing your wallpaper before setting a new one :

private void doStuff(Intent myIntent){

...

  for (int i = 0; i < File_Array.size(); i++) {
             Bitmap bitmap = BitmapFactory.decodeFile(File_Array.get(i));
             try {
                 myWallpaper.clear();
                 myWallpaper.setBitmap(bitmap);


             } catch (IOException e) {
                 e.printStackTrace();

             }

or try using the Method myWallpaper.forgetLoadedWallpaper(); (Min API 14)

A Honey Bustard
  • 3,433
  • 2
  • 22
  • 38