我知道这个标题已经有很多问题,但我仍然没有找到适合我案例的解决方案。
我有以下代码从在线数据库中获取用户数据。正如标题中所述,问题是AsyncTask
没有开始。
这是我的代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getData(); // retrieves "friends" data from database
FloatingActionButton btn3 = (FloatingActionButton) findViewById(R.id.button_add_new_friend);
btn3.setBackgroundTintList(getResources().getColorStateList(R.color.Blonde));
btn3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LayoutInflater layoutInflater = LayoutInflater.from(profile.this);
View promptView = layoutInflater.inflate(R.layout.input_new_friend, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(profile.this);
alertDialogBuilder.setView(promptView);
final EditText editText1 = (EditText) promptView.findViewById(R.id.edittext_addnewfriend);
// setup a dialog window
alertDialogBuilder.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
InputStream is = null;
// add values to the database
String friend = "" + editText1.getText();
// Verify the user in the USERS database - get users data from the dabase
GetDataJSON g = new GetDataJSON();
g.execute();
if (friends.contains(friend)) // if you are already friends with that user
Toast.makeText(getApplicationContext(), "You are already friends with that user!",
Toast.LENGTH_LONG).show();
else {
if (!users.contains(friend)) // the user doesn't exist in our database
Toast.makeText(getApplicationContext(), "That user doesn't exist! You either haven't introduced the right email or he's not a registered user within Poinder.",
Toast.LENGTH_LONG).show();
else // the user exists so we add him to the friends list
{
//do something
}
}
// Getting the users
protected void showList2(){
try {
JSONObject jsonObj = new JSONObject(myJSON);
people = jsonObj.getJSONArray(TAG_RESULTS);
for(int i=0;i<people.length();i++){
JSONObject c = people.getJSONObject(i);
String user = c.getString(TAG_USER);
String email = c.getString(TAG_EMAIL);
Double location_latitude = c.getDouble(TAG_LATITUDE);
Double location_longitude = c.getDouble(TAG_LONGITUDE);
users.add(email);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
// Getting the users
private class GetDataJSON extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost("http://xxxxxxx/friends_out.php");
// Depends on your web service
httppost.setHeader("Content-type", "application/json");
InputStream inputStream = null;
String result = null;
try {
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
// json is UTF-8 by default
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
result = sb.toString();
} catch (Exception e) {
// Oops
}
finally {
try{if(inputStream != null)inputStream.close();}catch(Exception squish){}
}
return result;
}
@Override
protected void onPostExecute(String result){
myJSON=result;
showList2();
}
}
知道我应该使用什么其他方法吗?或者最好是我应该如何修改这个以及我的AsyncTask
永远不会开始的任何想法?
编辑:我应用了下面提到的所有建议,但遗憾的是到目前为止它们都没有工作(我的AsyncTask
仍然没有开始)。
另一个问题:在同一个活动中使用多个AsyncTask
与我的问题有关吗?
答案 0 :(得分:21)
由于(我假设)没有其他建议的解决方案有效,我怀疑你的问题在于AsyncTask
的执行方式。如果在同一个Activity中正在执行多个AsyncTasks,就像在您的应用程序中一样,那么这些AsyncTasks将不会并行执行。他们将一个接一个地执行。
我怀疑你的其他AsyncTask是长期运行的,所以你的GetDataJSON
AsyncTask正在等待其他任务完成。
解决方案是启用AsyncTask的并行执行。使用以下代码并行执行AsyncTasks。
GetDataJSON g = new GetDataJSON();
g.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
来自AsyncTask docs:
执行顺序
首次引入时,AsyncTasks在单个后台线程上串行执行。从DONUT开始,这被改为一个线程池,允许多个任务并行运行。从HONEYCOMB开始,任务在单个线程上执行,以避免由并行执行引起的常见应用程序错误。
如果您真的想要并行执行,可以使用THREAD_POOL_EXECUTOR调用executeOnExecutor(java.util.concurrent.Executor,Object [])。
希望这有帮助。
答案 1 :(得分:10)
只需更改你的asyntask参数
class GetDataJSON extends AsyncTask<String, Void, String>
to,
class GetDataJSON extends AsyncTask<Void, Void, String>
答案 2 :(得分:7)
根据您的问题,我得出结论,您正在尝试从服务器获取好友列表,并根据结果显示Toast消息。
根据您的代码,您不会从alertDialogBuilder创建和显示AlertDialog。尝试显示AlertBox。
AsyncTask在一个单独的线程中运行。因此,
if (friends.contains(friend))
将立即执行
g.execute();
因此,即使用户在朋友列表中,也会显示其他部分的Toast。
另外,您没有将日志放在Asynctask方法中,这可能会让您觉得AsyncTask没有运行。
我建议您将if
条件代码从AlertDialog
的{{1}}移至onPostExecute()
方法,并将其放在GetDataJSON
之后。
另外,在AsyncTask方法中放入一些日志。
希望这会有所帮助。请找到以下代号:
showList2();
答案 3 :(得分:4)
在getData2()方法内部试试这个:
new AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
// your code
}
@Override
protected void onPostExecute(String result){
// your code
}
}.execute();
或者如果它不起作用,将AsyncTask类放在外部方法然后直接调用执行AsyncTask类而不是getData2(),就像这样
new GetDataJSON().execute();
答案 4 :(得分:3)
在Aysc Task中添加此覆盖方法。
@Override
protected void onPreExecute() {
super.onPreExecute();
}
我不知道你在这里尝试做什么,但是这段代码将在你的异步任务完成之前执行。
if (friends.contains(friend)) // if you are already friends with that user
Toast.makeText(getApplicationContext(), "You are already friends with that user!",
Toast.LENGTH_LONG).show();
else {
if (!users.contains(friend)) // the user doesn't exist in our database
Toast.makeText(getApplicationContext(), "That user doesn't exist! You either haven't introduced the right email or he's not a registered user within Poinder.",
Toast.LENGTH_LONG).show();
else // the user exists so we add him to the friends list
{
//do something
}
如果你希望这个代码在你的asyc任务完成后执行,那么在你的showList2()方法中添加这个代码。
顺便说一下,为什么要在内部方法中创建异步任务。这是个坏主意。 创建单独的aynch任务。这样你就可以使用其他活动了。
答案 5 :(得分:3)
在AsyncTask上添加构造函数
public GetDataJSON (){
}
添加onPreExecute以更加确定
@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(this /*or getActivity()*/,"IT'S WORKING!!!", Toast.LENGTH_LONG).show();
}
答案 6 :(得分:3)
我不认为强制严格模式有助于这种情况。在编写网络操作时(例如你在doInBackground方法中执行的操作),你应该使用AsyncTask而不是Strict Mode,这样你的UI就不会被阻止。
严格模式将强制操作在应用程序的主线程上运行,而AsyncTask在后台线程上运行。
答案 7 :(得分:2)
问题在于您的asynctask参数
谷歌的Android文档说:
异步任务由3种泛型类型定义,称为Params,Progress和Result,以及4个步骤,分别称为onPreExecute,doInBackground,onProgressUpdate和onPostExecute。
AsyncTask的通用类型:
异步任务使用的三种类型如下:
谷歌的Android文档说:
AsyncTask的通用类型:
异步任务使用的三种类型如下:
并非所有类型都始终由异步任务使用。要将类型标记为未使用,只需使用类型Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
因此,您不向AsyncTask发送任何参数,使您的异步任务如下所示
// Getting the users
public void getData2(){
new GetDataJSON().execute();
}
class GetDataJSON extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
/// your logic here
return result;
}
@Override
protected void onPostExecute(String result){
// your logic here
}
}
答案 8 :(得分:2)
这个问题的解决方案,很常见,我介绍到我当前的开发是AsyncService,我不会使用这个库的所有功能(疼痛系统),但功能强大,它还可以帮助您清理代码你的活动。
我不知道是否存在另一个解决方案,可以帮助开发人员分离问题并清理代码(在我的意思是Android),这是我尝试过的最好的,也许你应该试一试。当然,它可以帮助您解决当前的问题。
希望它有所帮助。