2011-10-08 5 views
0

J'ai un service qui extrait le code html d'une URL, le convertit en texte seulement (avec Jsoup) et vérifie quelque chose sur la chaîne, et si certaines conditions sont vraies, il lance une notification et écrit quelque chose dans un fichier. Pour autant que je sache, ce type de service ne devrait pas prendre beaucoup de mémoire, et dans Watchdog, il prend ~ 65 Mo, et c'est beaucoup trop. Il faut plus que tout autre processus (même plus que tw launcher et Android System). Je voudrais que vous me disiez ce que j'ai fait de mal.Le service prend trop de mémoire

Heres ma classe de service:

public class NotifyService extends Service 
{ 
    private int number=0; 
    private Timer timer=new Timer(); 
    private long INTERVAL=1*1000*60*60;//1 hour 

    public static String Oldhtml; 
    public static String Newhtml; 
    public static String currHtml; 


    // hooks main activity here  


    /* 
    * not using ipc...but if we use in future 
    */ 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onCreate() 
    { 
     super.onCreate();  

     _startService(); 
     Log.w("myApp", "START"); 
    } 

    @Override 
    public void onDestroy() 
    { 
     super.onDestroy(); 

     _shutdownService(); 
     Log.w("myApp", "STOPPED"); 

    } 


    /* 
    * starting the service 
    */ 
    private void _startService() 
    {  
     timer.scheduleAtFixedRate(new TimerTask() { 

     public void run() { 
      try { 
       doServiceWork(); 
      } catch (ClientProtocolException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } catch (IOException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 
      try { 
       Thread.sleep(INTERVAL); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    },0,INTERVAL); 
     ; 
    } 




    /* 
    * start the processing, the actual work, getting config params, get data from network etc 
    */ 
    private void doServiceWork() throws ClientProtocolException, IOException 
    { 
     String FILENAME="blichData"; 
     String info=null; 
     String classLetter = null,classNum1=null; 
     int classNum = 0; 
     try{ 
      FileInputStream fis=openFileInput(FILENAME); 
      byte[] dataArray = new byte[fis.available()]; 
      while(fis.read(dataArray)!=-1) 
      { 
       info = new String(dataArray); 
      } 
      classLetter = info.substring(0, info.lastIndexOf(" ")); 
      classNum1 =info.substring(info.lastIndexOf(" ")+1); 
      classNum=Integer.parseInt(classNum1); 
      fis.close(); 
     }catch (Exception e){ 

     } 
     if (classLetter!=null && classNum1!=null) { 
      Oldhtml=readHTMLfromFile(); 
     if (GetHTML.isHavingChanges(classLetter,classNum)) 
     { 
      myNotify(); 
      writeHTMLtoFile(currHtml); 
      /* 
      try { 
       String data= "false"; 
       FileOutputStream fos = openFileOutput("blichService", Context.MODE_PRIVATE); 
       fos = openFileOutput("blichService",Context.MODE_PRIVATE); 
       fos.write(data.getBytes()); 
       fos.close(); 
       } 
       catch (Exception e) {} 
       */ 
     } 
     } 
; 
     } 



    /* 
    * shutting down the service 
    */ 
    private void _shutdownService() 
    { 
     if (timer != null) timer.cancel(); 
     Log.i(getClass().getSimpleName(), "Timer stopped..."); 
    } 
    public void writeHTMLtoFile(String html) { 
     try { 
      String FILENAME = "blichNotifyData"; 
      String data= html; 
      FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE); 
      fos = openFileOutput(FILENAME,Context.MODE_PRIVATE); 
      fos.write(data.getBytes()); 
      fos.close(); 

     } 
      catch (Exception e){} 
    } 
    public String readHTMLfromFile() { 
     String FILENAME = "blichNotifyData"; 
     String info=""; 
     try{ 
      FileInputStream fis=openFileInput(FILENAME); 
      if (fis.available()>0) 
      { 
      byte[] dataArray = new byte[fis.available()]; 
      while(fis.read(dataArray)!=-1) 
      { 
      info = new String(dataArray); 
      } 
      fis.close(); 
      } 
     else { 
      Oldhtml="null"; 
     } 
     } 
     catch (Exception e) {} 
     return info; 

} 
    public void myNotify() 
    { 
     NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
     Intent intent= new Intent (this,SchoolBlichActivity.class); 
     PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT); 
     String body = " בליך"; 
     String title = "ישנם שינויים חדשים!"; 
     Notification n =new Notification(R.drawable.table, body, System.currentTimeMillis()); 
     n.flags |=Notification.FLAG_AUTO_CANCEL; 
     n.setLatestEventInfo(getApplicationContext(), title, body, pi); 
     n.defaults = Notification.DEFAULT_ALL; 
     number++; 
     n.number=number; 
     nm.notify(0,n); 


    } 

    } 

Et si elle est nécessaire, la classe d'extraction HTML:

public class GetHTML { 
    public static boolean isHavingChanges(String classLetter,int classNum) throws ClientProtocolException, IOException { 
      int classLetterCode = 0; 
      int timeTableCode=1; 
      if (classLetter.equals("ט")) 
       classLetterCode=0; 
      else if (classLetter.equals("י")) 
       classLetterCode=1; 
      else if (classLetter.equals("יא")) 
       classLetterCode=2; 
      else if (classLetter.equals("יב")) 
       classLetterCode=3; 
      switch(classLetterCode) 
      { 
      case 0: 
       if (classNum>=1 && classNum<=7) 
        timeTableCode=1; 
       else if (classNum>7 && classNum<=14) 
        timeTableCode=2; 
       break; 
      case 1: 
       if (classNum>=1 && classNum<=7) 
        timeTableCode=3; 
       else if (classNum>7 && classNum<=14) 
        timeTableCode=4; 
       break; 
      case 2: 
       if (classNum>=1 && classNum<=7) 
        timeTableCode=5; 
       else if (classNum>7 && classNum<=14) 
        timeTableCode=6; 
       break; 
      case 3: 
       if (classNum>=1 && classNum<=7) 
        timeTableCode=7; 
       else if (classNum>7 && classNum<=14) 
        timeTableCode=8; 
       break; 
      } 
      String url = "http://blich.iscool.co.il/DesktopModules/IS.TimeTable/MainScreen.aspx?pid=17&mid=6264&page="+timeTableCode+"&msgof=0&static=1"; 
     HttpClient client = new DefaultHttpClient(); 
     HttpGet request = new HttpGet(url); 
     HttpResponse response = client.execute(request); 

     String html = ""; 
     InputStream in = response.getEntity().getContent(); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
     StringBuilder str = new StringBuilder(); 
     String line = null; 
     while((line = reader.readLine()) != null) 
     { 
      str.append(line); 
     } 
     in.close(); 
     html = str.toString(); 
     html = Jsoup.parse(html).text(); 
     if (NotifyService.Oldhtml.equalsIgnoreCase(html)) { 
      return false; 
     } 
     if (timeTableCode%2!=0){ 
      for (int i=0;i<8;i++) { 
       if (!html.contains(i+" "+i)) { 
        NotifyService.currHtml=html; 
         return true; 
        } 

       } 
      } 

     if (timeTableCode%2==0) { 
      for (int i=8;i<15;i++) { 
       if (!html.contains(i+" "+i)) { 
        NotifyService.currHtml=html; 
         return true; 
       } 
      } 
     } 

     return false; 
} 
} 

Ignore la langue étrangère. xD Je veux juste comprendre ce que j'ai fait de mal? Merci

Répondre

1

Bien que je ne puisse pas savoir exactement quelle partie de votre code est problématique, vous pouvez essayer d'analyser l'utilisation de la mémoire via un vidage de mémoire pris avec DDMS en utilisant Eclipse MAT. Vous devrez utiliser l'outil hprofconv pour convertir votre vidage de tas Android dans un format que MAT comprend.

Pour obtenir le HPL Dump de HPROF, ouvrez le Dalvik Debug Monitor (DDMS), connectez-le à votre émulateur, sélectionnez le processus de votre application et cliquez sur l'icône "Dump HPROF file".

+0

Je suis désolé mais je n'ai pas compris ... pouvez-vous m'expliquer comment faire? –

+0

Je recommande la session [Gestion de la mémoire pour les applications Android] (http://www.google.com/events/io/2011/sessions/memory-management-for-android-apps.html) de cette année Google I/O . Beaucoup de ces choses sont expliquées et montrées là, y compris l'utilisation de base de MAT. –

+0

user974485: J'ai ajouté quelques informations de base à ma réponse. Pour plus de détails, la vidéo référencée par alextsc est certainement un bon début. –