服务占用太多内存

发布于 2024-12-08 22:21:08 字数 8177 浏览 0 评论 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 我只是想了解我做错了什么? 谢谢

I have a service that extracting html code from an URL, converting it to text only (with Jsoup) and then checks something on the string, and if some conditions are true it launches a notification and writes something to a file.
As far as I know, this kind of service shouldn't take much memory, and in Watchdog, it takes ~65 MB, and it is way too much. It takes more than any other process (even more than tw launcher and Android System).
I would like you to tell me what have I done wrong.

Heres my service class:

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


    }

    }

And if it is needed, the HTML extracting class:

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 the foreign language. xD
I just want to understand what have I done wrong?
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏日浅笑〃 2024-12-15 22:21:08

虽然我无法直接判断代码的哪一部分有问题,但您可以尝试使用 Eclipse MAT 通过 DDMS 获取的堆转储来分析内存使用情况。您需要使用 hprofconv 工具将 Android 堆转储转换为 MAT 可以理解的格式。

要获取 HPROF 堆转储,请打开 Dalvik 调试监视器 (DDMS),将其连接到您的模拟器,选择应用程序的进程,然后单击“转储 HPROF 文件”图标。

While I cannot tell out-of-the-box what portion of your code is problematic, you may try to analyze the memory usage through a heap dump taken with DDMS using Eclipse MAT. You will need to use the hprofconv tool to convert your Android heap dump into a format that MAT understands.

To get the HPROF Heap Dump, open the Dalvik Debug Monitor (DDMS), connect it you your emulator, select the process of your application and hit the "Dump HPROF file" icon.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文