2014-11-08 81 views
1

我已經創建了一個應用程序,可以從我的服務器上的XML文件中提取數據(招聘廣告),並在我的應用程序中顯示這些招聘廣告。當我查看我的應用程序時,它使用的是30-50mb,我相信這對於這樣一個簡單的應用程序來說太多了。我嘗試在一些低端設備(24MB堆大小)上運行它,它工作正常,有點滯後,但沒有OOM或任何其他崩潰,所以我不認爲這是一個內存泄漏。如何降低我的應用程序的內存使用量?

我使用全局數組,每個初始大小爲100,一旦加載XML文件,數組將被調整爲XML文件中節點的數量。

全局變量

private final Integer MAX_SIZE = 100; 
    public String[] ID = new String[MAX_SIZE]; 
    public String[] Category = new String[MAX_SIZE]; 
    public String[] Title = new String[MAX_SIZE]; 
    public String[] Content = new String[MAX_SIZE]; 
    public String[] Link = new String[MAX_SIZE]; 
    public Integer[] JobID = new Integer[MAX_SIZE]; 
    public String[] nID = new String[MAX_SIZE]; 
    public String[] nCategory = new String[MAX_SIZE]; 
    public String[] nTitle = new String[MAX_SIZE]; 
    public String[] nContent = new String[MAX_SIZE]; 
    public String[] nLink = new String[MAX_SIZE]; 
    public int[] nJobID = new int[MAX_SIZE]; 
    public int[] nExists = new int[MAX_SIZE]; 

這是我使用的XML和加載項提取到變量

private class LOADXML extends AsyncTask<String, Void, Void> { 

     @Override 
     protected void onPreExecute() { 
      if (swipeLayout != null) { 
       if (!swipeLayout.isRefreshing()) { 
        ((MainActivity) getActivity()).load(); 
       } 
      } else { 
       ((MainActivity) getActivity()).load(); 
      } 

      Arrays.fill(((MainActivity) getActivity()).jobCOUNT, 0); 
     } 

     @Override 
     protected Void doInBackground(String... urls) { 
      if (getActivity() == null) { 
       cancel(true); 
      } 
      if (!((MainActivity) getActivity()).fromNotif && ((MainActivity) getActivity()).refresh) { 
       try { 
        XMLParser parser = new XMLParser(); 
        String xml = parser.getXmlFromUrl(URL); // getting XML 
        Document doc = parser.getDomElement(xml); // getting DOM element 

        Context cx = getActivity(); 

        WriteXMLToFile(xml, cx); 


        NodeList nl = doc.getElementsByTagName(KEY_JOB); 
        listSize = 0; 

        SetArrayLength(nl.getLength()); 

        // looping through all item nodes <item> 
        for (int i = 0; i < nl.getLength(); i++) { 
         if (getActivity() == null) { 
          cancel(true); 
         } 
         Element e = (Element) nl.item(i); 

         listSize += 1; 
         setGlobalVars(listSize - 1, parser.getValue(e, KEY_ID), parser.getValue(e, KEY_CATEGORY), parser.getValue(e, KEY_TITLE), parser.getValue(e, KEY_CONTENT), parser.getValue(e, KEY_LINK), parser.getValue(e, KEY_JOBID)); 
        } 

       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
      return null; 
     } 


     @Override 
     protected void onPostExecute(Void result) { 
      Activity activity = getActivity(); 
      if (activity != null && !isCancelled()) { 
       ((MainActivity) getActivity()).unload(); 
       ((MainActivity) getActivity()).refresh = false; 

       updateCountVar(); 
       updateList(); 
       if (swipeLayout.isRefreshing()) { 
        LinearLayout container = (LinearLayout) vw.findViewById(frag_container); 
        container.removeAllViews(); 

        if (swipeLayout != null) { 
         swipeLayout.setRefreshing(false); 
         isRefreshing = false; 
        } 

        showJobBox(li, vw); 
       } else { 
        showJobBox(li, vw); 
       } 
      } 
     } 
    } 

的代碼,這是代碼的一部分,負責填充片段與數據

listSize = ((MainActivity) getActivity()).nID.length; 

      for (Integer i = 0; i < listSize; i++) { 
       if (filterEntry(i) && (Integer.valueOf(((MainActivity) getActivity()).nJobID[i]) != null)) { 
        // Layout params 
        @SuppressLint("InflateParams") View item_layout = inflater.inflate(R.layout.job_box, null, false); 
        LinearLayout container = (LinearLayout) view.findViewById(frag_container); 
        TextView category = (TextView) item_layout.findViewById(R.id.jobBox_category); 
        TextView title = (TextView) item_layout.findViewById(R.id.jobBox_title); 
        TextView description = (TextView) item_layout.findViewById(R.id.jobBox_description); 
        TextView jobBtn = (TextView) item_layout.findViewById(R.id.jobBox_button); 
        TextView jobIDbox = (TextView) item_layout.findViewById(R.id.jobIDbox); 
        ImageButton imgBtn = (ImageButton) item_layout.findViewById(R.id.imageButton); 
        TextView newLabel = (TextView) item_layout.findViewById(R.id.jobBox_new); 

        Integer nExistsInteger = ((MainActivity) getActivity()).nExists[i]; 

        if (nExistsInteger == 0) { 
         newLabel.setVisibility(View.VISIBLE); 
        } 
        // ############################################## 
        int id = i + 10000; 

        item_layout.setId(id); 

        category.setText(((MainActivity) getActivity()).nCategory[i]); 
        title.setText(((MainActivity) getActivity()).nTitle[i]); 
        description.setText(((MainActivity) getActivity()).nContent[i]); 
        Integer ido = ((MainActivity) getActivity()).nJobID[i]; 
        jobIDbox.setText("Šifra oglasa: " + String.valueOf(ido)); 

        final Integer a = i; 
        jobBtn.setOnClickListener(new View.OnClickListener() { 

         @Override 
         public void onClick(View view) { 
          String url = ((MainActivity) getActivity()).Link[a]; 
          Intent i = new Intent(Intent.ACTION_VIEW); 
          i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 
          i.setData(Uri.parse(url)); 
          startActivity(i); 
         } 
        }); 

        imgBtn.setOnClickListener(new View.OnClickListener() { 

         @Override 
         public void onClick(View view) { 
          Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); 
          sharingIntent.setType("text/plain"); 
          sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Studentski posao"); 
          sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, ((MainActivity) getActivity()).nTitle[a] 
            + " - " + ((MainActivity) getActivity()).nLink[a] 
            + " (Via http://bit.ly/StudentServis)"); 
          startActivity(Intent.createChooser(sharingIntent, "Podijeli koristeći")); 
         } 
        }); 

        RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); 
        if (i > 0) { 
         params1.addRule(RelativeLayout.ALIGN_BOTTOM, id - 1); 
         item_layout.setLayoutParams(params1); 
        } else { 
         item_layout.setPadding(10, 10, 10, 10); 
        } 

        container.addView(item_layout); 
        if (i == listSize - 1) { 
         @SuppressLint("InflateParams") View item_layout_dummy = inflater.inflate(R.layout.dummy, null); 
         container.addView(item_layout_dummy); 
        } 
        ((MainActivity) getActivity()).ID[i] = ((MainActivity) getActivity()).nID[i]; 
        ((MainActivity) getActivity()).Category[i] = ((MainActivity) getActivity()).nCategory[i]; 
        ((MainActivity) getActivity()).Title[i] = ((MainActivity) getActivity()).nTitle[i]; 
        ((MainActivity) getActivity()).Content[i] = ((MainActivity) getActivity()).nContent[i]; 
        ((MainActivity) getActivity()).Link[i] = ((MainActivity) getActivity()).nLink[i]; 
        ((MainActivity) getActivity()).JobID[i] = ((MainActivity) getActivity()).nJobID[i]; 
       } 
      } 

我確信,當片段切換(到diffe租賃類別),如果數據已經被加載,LOADXML doInBackground被跳過。

我的問題是,是否有一個更高效和更友善的方法來實現這一目標?這是我的第一個具有動態內容的應用程序。

回答

2

階段1)使用對象。

溝陣列。你使用它們的方式是無效的,系統可以爲你做很多工作。你至少會使用一半的內存。

在您的活動,而不是大量的陣列(也重複)只有一個列表:

private ArrayList<Job> jobs = new ArrayList<Job>(); 

與它一起爲您創造就業機會持有人模式類。

public static class Job { 
    public int jobId; 
    public String id, category, title, content, link; 
    public boolean exists; 
} 

上述內容可幫助您避免使用多個陣列無效管理數據。

現在重寫您的XML加載任務以將所有作業加載到後臺列表中。只有完成後才能開始更新視圖。

私有類的loadXML擴展的AsyncTask> {

@Override 
protected void onPreExecute() { 
    // 
} 

@Override 
protected List<Job> doInBackground(String... urls) { 
    try { 
     final List<Job> jobs = new ArrayList<Job>(); 

     // this method is written in pseudo code as I don't know anything about parsing XML 

     // assume one url containing all jobs 
     String xml = getXmlFromUrl(urls[0]); 

     // loop through each Job element 
     for(Element e : doc) { 
      // create a new Job instance 
      Job job = new Job(); 

      // load the Job data 
      job.id = e.getAttribute("id"); 
      // etc. 

      // add the Job to the list 
      jobs.add(job); 
     } 

     // return Job list 
     return jobs; 
    } catch (Exception ex) { 
     ex.printStackTrace(); 

     // if anything fails, return null to indicate 
     return null; 
    } 
} 

@Override 
protected void onPostExecute(List<Job> result) { 
    // send the list to activity and let it handle it 
    ((MainActivity)getActivity()).updateJobList(result); 

    // MainActivity.updateJobList() will contain pretty much what was here. 
} 

}

階段2)限制數據使用

您不需要下載所有作業一次。下載十個,當用戶到達列表的末尾時,允許他下載另外十個。但是這個話題超出了這篇文章。

+0

謝謝。現在工作正常。沒有什麼區別,但它感覺比以前更快,反應更快,而且這樣更容易理解代碼,至少對我而言。 – 2014-11-10 17:48:52

相關問題