Android - AsyncTask没有执行

时间:2015-08-12 06:44:36

标签: android android-asynctask

我知道这个标题已经有很多问题,但我仍然没有找到适合我案例的解决方案。

我有以下代码从在线数据库中获取用户数据。正如标题中所述,问题是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与我的问题有关吗?

9 个答案:

答案 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消息。

根据您的代码,您不会从alertDialogBu​​ilder创建和显示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的通用类型:

异步任务使用的三种类型如下:

  1. Params,执行时发送给任务的参数类型。
  2. 进展,期间发布的进度单位的类型 背景计算。
  3. 结果,背景计算结果的类型。
  4. 并非所有类型都始终由异步任务使用。要将类型标记为未使用,只需使用类型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,我不会使用这个库的所有功能(疼痛系统),但功能强大,它还可以帮助您清理代码你的活动。

  1. 使用@AsyncService注释
  2. 声明要使用@AsyncService注释检索数据的服务
  3. 您在活动中注入服务
  4. 在任何需要的地方致电您的服务
  5. 使用注释@OnMessage在您的活动中声明一个方法,您将在其中处理服务响应......
  6. AsyncService GitHub Wiki

    我不知道是否存在另一个解决方案,可以帮助开发人员分离问题并清理代码(在我的意思是Android),这是我尝试过的最好的,也许你应该试一试。当然,它可以帮助您解决当前的问题。

    希望它有所帮助。