- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个应用程序,它从我服务器上的 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);
}
}
}
}
这是负责用数据填充 fragment 的代码部分
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];
}
}
我确保当 fragment 切换(到不同的类别)时,如果数据已经加载,则跳过 LOADXML doInBackground。
我的问题是,是否有更高效、内存更友好的方法来实现这一点?这是我的第一个具有动态内容的应用程序。
最佳答案
阶段 1) 使用对象。
沟渠阵列。你使用它们的方式是无效的,系统可以为你做很多工作。您将至少使用一半的内存。
在您的 Activity 中只有一个列表而不是众多数组(也重复):
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 加载任务以在后台将所有作业加载到列表中。只有完成后才开始更新 View 。
私有(private)类 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 阶段)限制数据使用
您不需要一次下载所有作业。下载十个,当用户到达列表末尾时允许他下载另外十个。但这个话题超出了这篇文章的范围。
关于android - 如何降低我的应用程序的内存使用量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26817969/
我正在通过 labrepl 工作,我看到了一些遵循此模式的代码: ;; Pattern (apply #(apply f %&) coll) ;; Concrete example user=> (a
我从未向应用商店提交过应用,但我会在不久的将来提交。 到目前为止,我对为 iPhone 而非 iPad 进行设计感到很自在。 我了解,通过将通用PAID 应用放到应用商店,客户只需支付一次就可以同时使
我有一个应用程序,它使用不同的 Facebook 应用程序(2 个不同的 AppID)在 Facebook 上发布并显示它是“通过 iPhone”/“通过 iPad”。 当 Facebook 应用程序
我有一个要求,我们必须通过将网站源文件保存在本地 iOS 应用程序中来在 iOS 应用程序 Webview 中运行网站。 Angular 需要服务器来运行应用程序,但由于我们将文件保存在本地,我们无法
所以我有一个单页客户端应用程序。 正常流程: 应用程序 -> OAuth2 服务器 -> 应用程序 我们有自己的 OAuth2 服务器,因此人们可以登录应用程序并获取与用户实体关联的 access_t
假设我有一个安装在用户设备上的 Android 应用程序 A,我的应用程序有一个 AppWidget,我们可以让其他 Android 开发人员在其中以每次安装成本为基础发布他们的应用程序推广广告。因此
Secrets of the JavaScript Ninja中有一个例子它提供了以下代码来绕过 JavaScript 的 Math.min() 函数,该函数需要一个可变长度列表。 Example:
当我分别将数组和对象传递给 function.apply() 时,我得到 NaN 的 o/p,但是当我传递对象和数组时,我得到一个数字。为什么会发生这种情况? 由于数组也被视为对象,为什么我无法使用它
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界. 这篇CFSDN的博客文章ASP转换格林威治时间函数DateDiff()应用由作者收集整理,如果你
我正在将列表传递给 map并且想要返回一个带有合并名称的 data.frame 对象。 例如: library(tidyverse) library(broom) mtcars %>% spl
我有一个非常基本的问题,但我不知道如何实现它:我有一个返回数据框,其中每个工具的返回值是按行排列的: tmp<-as.data.frame(t(data.frame(a=rnorm(250,0,1)
我正在使用我的 FB 应用创建群组并邀请用户加入我的应用群组,第一次一切正常。当我尝试创建另一个组时,出现以下错误: {"(OAuthException - #4009) (#4009) 在有更多用户
我们正在开发一款类似于“会说话的本”应用程序的 child 应用程序。它包含大量用于交互式动画的 JPEG 图像序列。 问题是动画在 iPad Air 上播放正常,但在 iPad 2 上播放缓慢或滞后
我关注 clojure 一段时间了,它的一些功能非常令人兴奋(持久数据结构、函数式方法、不可变状态)。然而,由于我仍在学习,我想了解如何在实际场景中应用,证明其好处,然后演化并应用于更复杂的问题。即,
我开发了一个仅使用挪威语的应用程序。该应用程序不使用本地化,因为它应该仅以一种语言(挪威语)显示。但是,我已在 Info.plist 文件中将“本地化 native 开发区域”设置为“no”。我还使用
读完 Anthony's response 后上a style-related parser question ,我试图说服自己编写单体解析器仍然可以相当紧凑。 所以而不是 reference ::
multicore 库中是否有类似 sapply 的东西?还是我必须 unlist(mclapply(..)) 才能实现这一点? 如果它不存在:推理是什么? 提前致谢,如果这是一个愚蠢的问题,我们深表
我喜欢在窗口中弹出结果,以便更容易查看和查找(例如,它们不会随着控制台继续滚动而丢失)。一种方法是使用 sink() 和 file.show()。例如: y <- rnorm(100); x <- r
我有一个如下所示的 spring mvc Controller @RequestMapping(value="/new", method=RequestMethod.POST) public Stri
我正在阅读 StructureMap关于依赖注入(inject),首先有两部分初始化映射,具体类类型的接口(interface),另一部分只是实例化(请求实例)。 第一部分需要配置和设置,这是在 Bo
我是一名优秀的程序员,十分优秀!