簡體   English   中英

如何降低我的應用程序的內存使用率?

[英]How to lower my app's memory usage?

我創建了一個應用程序,該應用程序從服務器上的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];
                }
            }

我確保在切換片段(到另一個類別)時,如果已經加載了數據,則將跳過LOADXML doInBackground。

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

階段1)使用對象。

溝渠陣列。 您使用它們的方式無效,系統可以為您完成很多工作。 您將至少使用一半的內存。

在您的活動中,只有一個列表,而不是多個數組(也重復):

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

連同它為您的工作創建一個Holder模式類。

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)限制數據使用

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM