I am new to android development and software programming in general and believe I have a threading issue in my app. What the app does is searches for two sets of results based on two queries to an api and stores each set of results in its own list. A new list is generated containing only the elements that are in both lists. The app runs in a virtual device on my desktop but hangs on my Galaxy Nexus. I am using arraylist for this but I am wondering if perhaps hashset would be faster at accomplishing this type of operation. Below is my main activity. getfirst and secondID are done in an asynctask as well as getfirst and secondtitle in order to prevent networkonmainthread exception. Is that the best way to thread this application? Thanks for any help.
我是Android开发和软件编程的新手,并且相信我的应用程序中存在线程问题。该应用程序所做的是根据对api的两个查询搜索两组结果,并将每组结果存储在自己的列表中。生成一个新列表,其中仅包含两个列表中的元素。该应用程序在我的桌面上的虚拟设备中运行,但挂在我的Galaxy Nexus上。我正在使用arraylist,但我想知道是否hashset在完成这种类型的操作时会更快。以下是我的主要活动。 getfirst和secondID在asynctask以及getfirst和secondtitle中完成,以防止networkonmainthread异常。这是线程化这个应用程序的最佳方法吗?谢谢你的帮助。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.totlayout);
//set the UI elements
searchOne = (EditText) findViewById(R.id.searchOne);
searchTwo = (EditText) findViewById(R.id.searchTwo);
findMovies = (Button) findViewById(R.id.findMovies);
searchOne.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
//make person search url1
final StringBuilder personSearchURLOne = new StringBuilder(getName.getName1(searchOne));
searchURLOne = personSearchURLOne.toString();
return false;
}
});
searchTwo.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
//make person search url2
final StringBuilder personSearchURLTwo = new StringBuilder(getName.getName2(searchTwo));
searchURLTwo = personSearchURLTwo.toString();
return false;
}
});
}
public void getData(String searchURLOne, String searchURLTwo){
try{
//get ID 1
idOne = new getFirstID().execute(searchURLOne).get();
Log.d("JSONArray idOne", idOne.toString());
//get ID 2
idTwo = new getSecondID().execute(searchURLTwo).get();
Log.d("JSONArray idTwo", idTwo.toString());
//make credit search url1
final StringBuilder creditURLOne = new StringBuilder(buildCreditURL.getCreditURLOne(idOne));
final String creditOne = creditURLOne.toString();
Log.d("creditOne contains", creditOne);
//make credit search url2
final StringBuilder creditURLTwo = new StringBuilder(buildCreditURL.getCreditURLTwo(idTwo));
final String creditTwo = creditURLTwo.toString();
//get array of tiles for credit url 1
titleOne = new getFirstTitle().execute(creditOne).get();
Log.d("titleOne Contains", titleOne.toString());
//get array of titles for credit url 2
titleTwo = new getSecondTitle().execute(creditTwo).get();
//parse out common films into new array
myCommonFilms = new ArrayList<String>(commonFilms.getCommonFilms(titleOne, titleTwo));
}
catch(InterruptedException e){
e.printStackTrace();
}catch(ExecutionException e){
e.printStackTrace();
}
}
public void displayResults(View view) throws InterruptedException, ExecutionException{
//do something in response to button
getData(searchURLOne, searchURLTwo);
Intent intent = new Intent(this, DisplayResultsActivity.class).putStringArrayListExtra("myCommonFilmsList", myCommonFilms);
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.totlayout, menu);
return true;
}
}
3 个解决方案
#1
0
I think it's the correct way : using AsyncTask is an easy way to prevent your app for freezing the UI.
我认为这是正确的方法:使用AsyncTask是一种简单的方法来阻止您的应用程序冻结UI。
But I don't really understand what the following line do.
但我真的不明白以下几行是做什么的。
idOne = new getFirstID().execute(searchURLOne).get();
Actually, I never see it before. Anyway, how many records are you managing in your ArrayList ? 10, 100, 1000, 1 000 000 ?
实际上,我以前从未见过它。无论如何,你在ArrayList中管理了多少条记录? 10,100,1000,1 000 000?
If you're working with a lot of records, your phone will take a certain amount of time to accomplish the operations and you'll not be able to reduce it. The only solution, if the set is too large, is to trying to reduce it maybe directly on your server or when you're building your ArrayList.
如果您正在处理大量记录,您的手机将花费一定的时间来完成操作,您将无法减少它。如果集合太大,唯一的解决方案是尝试直接在服务器上或在构建ArrayList时减少它。
#2
0
I'm not necessarily following where the AsyncTask is created and put into action but it seems like it would be a good idea to put the entire getData method on the AsyncTask. That aside, if it works on the and but not on the device my 1st suspicion would be network access. Make sure your device has access not only to the internet but to the service that it needs to run the remote query on. It's very common to misunderstand that phones cannot see the same host computers as our desktops can. Also, if you're phone is roaming on Wifi check that the Wifi network will allow the service to be accessed. Is the remote query service a web service? Is it a DBMS SQL call you are trying to run? does the query require a specific network port?
我不一定要关注AsyncTask的创建和实施,但似乎将整个getData方法放在AsyncTask上是个好主意。除此之外,如果它在设备上工作但不在设备上工作,我首先怀疑是网络访问。确保您的设备不仅可以访问Internet,还可以访问运行远程查询所需的服务。误解手机看不到与台式机相同的主机是很常见的。此外,如果您的手机在Wifi上漫游,请检查Wifi网络是否允许访问该服务。远程查询服务是Web服务吗?它是您尝试运行的DBMS SQL调用吗?查询是否需要特定的网络端口?
#3
0
this one seems to block the UI thread:
这个似乎阻止了UI线程:
titleOne = new getFirstTitle().execute(creditOne).get();
better use a new thread for doing the long job , and once it finishes , notify the UI thread about the new data .
更好地使用新线程来完成长时间的工作,一旦完成,就通知UI线程有关新数据的信息。
you can use asyncTask to make it easier for you . if you prefer the normal threads ,either use a handler
(and use handler.post) or use runOnUiThread
once the thread has finished.
您可以使用asyncTask使您更轻松。如果您更喜欢普通线程,请使用处理程序(并使用handler.post)或在线程完成后使用runOnUiThread。
if you use a hanlder , don't forget to create it outside the of thread itself.
如果你使用hanlder,不要忘记在线程本身之外创建它。
as a new android developer , you should watch the google IO videos . they can help a lot . watch videos from 2010 to 2012 .
作为一名新的Android开发者,您应该观看Google IO视频。他们可以提供很多帮助。观看2010年至2012年的视频。
#1
0
I think it's the correct way : using AsyncTask is an easy way to prevent your app for freezing the UI.
我认为这是正确的方法:使用AsyncTask是一种简单的方法来阻止您的应用程序冻结UI。
But I don't really understand what the following line do.
但我真的不明白以下几行是做什么的。
idOne = new getFirstID().execute(searchURLOne).get();
Actually, I never see it before. Anyway, how many records are you managing in your ArrayList ? 10, 100, 1000, 1 000 000 ?
实际上,我以前从未见过它。无论如何,你在ArrayList中管理了多少条记录? 10,100,1000,1 000 000?
If you're working with a lot of records, your phone will take a certain amount of time to accomplish the operations and you'll not be able to reduce it. The only solution, if the set is too large, is to trying to reduce it maybe directly on your server or when you're building your ArrayList.
如果您正在处理大量记录,您的手机将花费一定的时间来完成操作,您将无法减少它。如果集合太大,唯一的解决方案是尝试直接在服务器上或在构建ArrayList时减少它。
#2
0
I'm not necessarily following where the AsyncTask is created and put into action but it seems like it would be a good idea to put the entire getData method on the AsyncTask. That aside, if it works on the and but not on the device my 1st suspicion would be network access. Make sure your device has access not only to the internet but to the service that it needs to run the remote query on. It's very common to misunderstand that phones cannot see the same host computers as our desktops can. Also, if you're phone is roaming on Wifi check that the Wifi network will allow the service to be accessed. Is the remote query service a web service? Is it a DBMS SQL call you are trying to run? does the query require a specific network port?
我不一定要关注AsyncTask的创建和实施,但似乎将整个getData方法放在AsyncTask上是个好主意。除此之外,如果它在设备上工作但不在设备上工作,我首先怀疑是网络访问。确保您的设备不仅可以访问Internet,还可以访问运行远程查询所需的服务。误解手机看不到与台式机相同的主机是很常见的。此外,如果您的手机在Wifi上漫游,请检查Wifi网络是否允许访问该服务。远程查询服务是Web服务吗?它是您尝试运行的DBMS SQL调用吗?查询是否需要特定的网络端口?
#3
0
this one seems to block the UI thread:
这个似乎阻止了UI线程:
titleOne = new getFirstTitle().execute(creditOne).get();
better use a new thread for doing the long job , and once it finishes , notify the UI thread about the new data .
更好地使用新线程来完成长时间的工作,一旦完成,就通知UI线程有关新数据的信息。
you can use asyncTask to make it easier for you . if you prefer the normal threads ,either use a handler
(and use handler.post) or use runOnUiThread
once the thread has finished.
您可以使用asyncTask使您更轻松。如果您更喜欢普通线程,请使用处理程序(并使用handler.post)或在线程完成后使用runOnUiThread。
if you use a hanlder , don't forget to create it outside the of thread itself.
如果你使用hanlder,不要忘记在线程本身之外创建它。
as a new android developer , you should watch the google IO videos . they can help a lot . watch videos from 2010 to 2012 .
作为一名新的Android开发者,您应该观看Google IO视频。他们可以提供很多帮助。观看2010年至2012年的视频。