2011-10-08 67 views
0

我有一個服務,從URL中提取html代碼,將其轉換爲僅文本(使用Jsoup),然後檢查字符串上的某些內容,如果某些條件爲真,則會啓動通知並寫入一些內容到一個文件。 據我所知,這種服務不應該佔用太多的內存,而在Watchdog中,它需要約65 MB,而且太多了。它比其他任何過程都要多(甚至超過tw啓動器和Android系統)。 我想你告訴我我做錯了什麼。服務需要太多內存

我的繼承人服務類:

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); 


    } 

    } 

而且如果需要的話,在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; 
} 
} 

忽略外語。 xD 我只想了解我做錯了什麼? 謝謝

回答

1

儘管我無法確定代碼中哪些部分存在問題,但您可以嘗試通過使用Eclipse MAT與DDMS進行堆轉儲來分析內存使用情況。您需要使用hprofconv工具將Android堆轉儲轉換爲MAT可以理解的格式。

要獲得HPROF堆轉儲,請打開Dalvik調試監視器(DDMS),將其連接到模擬器,選擇應用程序的進程並點擊「轉儲HPROF文件」圖標。

+0

很抱歉,但我不明白...你能解釋我該怎麼做嗎? –

+0

我推薦從今年的Google I/O [內存管理Android應用](http://www.google.com/events/io/2011/sessions/memory-management-for-android-apps.html)會話。這裏解釋並展示了很多這些東西,包括MAT的基本用法。 – 2011-10-08 09:24:12

+0

user974485:我在我的答案中添加了一些基本信息。有關更多詳情,alextsc引用的視頻肯定是一個好的開始。 –