【问题标题】:Android Async Task stop running after run it a few timesAndroid Async Task 运行几次后停止运行
【发布时间】:2011-12-12 12:53:22
【问题描述】:

我正在使用 AsyncTask 通过 Internet 下载数据,但遇到了一个小问题。我需要能够启动一个 AsyncTask 几次,这就是为什么我每次都创建一个新实例,但我注意到它在前三到四次没有任何问题,但之后我的 AsyncTask 是坚持onPreExecute(),之后什么也不做。难道我做错了什么 ? (实际上我一个接一个地使用两个 AsyncTask 只是为了测试目的)。这是我正在使用的示例代码:

这就是我启动 AsyncTasks 的方式:

    if (index == 1) {
        //Login - first way
        new FirstSync().execute(Synchronization.this);
    } else if (index == 2) {
        //SyncWithHash - second way
        SyncWithHash syncHash = new SyncWithHash();
        syncHash.execute(Synchronization.this);
    } else if (index == 3) {
        //Deactivate Collection - third way
        deactivateColl = new DeactivateCollection();
        deactivateColl.execute(Synchronization.this);
    }

我确实尝试了三种不同的方式来启动 asyncTask,但没有改变。这是我的 AsyncTask :

    // Sync With Hash
public class SyncWithHash extends AsyncTask <Context, Integer, Void> {
    @Override
    protected Void doInBackground(Context... arrContext) {
        try {

            String charset = "UTF-8";
            hash = getAuthHash();

            SharedPreferences lastUser = PreferenceManager.getDefaultSharedPreferences(Synchronization.this);
            int userId = lastUser.getInt("lastUser", 1);

            systemDbHelper = new SystemDatabaseHelper(Synchronization.this, null, 1);
            systemDbHelper.initialize(Synchronization.this);
            String sql = "SELECT dbTimestamp FROM users WHERE objectId=" + userId;
            Cursor cursor = systemDbHelper.executeSQLQuery(sql);
            if (cursor.getCount() < 0) {
                cursor.close();
            } else if (cursor.getCount() > 0) {
                cursor.moveToFirst();
                timeStamp = cursor.getString(cursor.getColumnIndex("dbTimestamp"));
                Log.d("", "timeStamp : " + timeStamp);
            }

                String query = String.format("debug_data=%s&"
                        + "client_auth_hash=%s&" + "timestamp=%s&"
                        + "client_api_ver=%s&"
                        + "set_locale=%s&" + "device_os_type=%s&"
                        + "device_sync_type=%s&"
                        + "device_identification_string=%s&"
                        + "device_identificator=%s&" + "device_resolution=%s",
                        URLEncoder.encode("1", charset),
                        URLEncoder.encode(hash, charset),
                        URLEncoder.encode(timeStamp, charset),
                        URLEncoder.encode(clientApiVersion, charset),
                        URLEncoder.encode(locale, charset),
                        URLEncoder.encode(version, charset),
                        URLEncoder.encode("14", charset),
                        URLEncoder.encode(version, charset),
                        URLEncoder.encode(deviceId, charset),
                        URLEncoder.encode(resolution, charset));

            SharedPreferences useSSLConnection = PreferenceManager
                    .getDefaultSharedPreferences(Synchronization.this);
            boolean useSSl = useSSLConnection.getBoolean("UseSSl", true);
            if (useSSl) {
                UseHttpsConnection(url, charset, query);
            } else {
                UseHttpConnection(url, charset, query);
            }
        } catch (Exception e2) {
            e2.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        //cancelDialog.setProgress(progress[0]);
    }
    @Override
    protected void onCancelled() {
        Log.d("","ON CANCELLED");
    } 
    @Override
    protected void onPreExecute() 
    {
        Log.d("","ON PRE EXECUTE");
       // myProgress = 0;
    }
    @Override
    protected void onPostExecute(Void v) {
        Log.d("","ON POST EXECUTE");
    }
  }

所以任何想法为什么它会发生,这是能够多次使用 AsyncTask 而没有任何异常和错误的最佳方法,就像我得到的那样。

还有一个问题:AsyncTask 中是否有任何东西会导致我的连接成为 Reset by peer ,因为我也遇到了这个错误(不是每次)。

非常感谢!

【问题讨论】:

  • 您好 Bombastic,您是否注意到您的任何异步线程是否从服务器获得响应?
  • 实际上每个 asynctask 一开始都会得到响应,但是运行几次后它们一直卡在onPreExecute,甚至一开始都没有显示来自doInBackground 的日志。
  • 您能解释一下您在问题中使用的getDefaultSharedPreferences(Synchronization.this) 是什么吗?

标签: android android-asynctask


【解决方案1】:

我认为你的 doInBackground() 挂了。进入和退出时做log语句并检查。

在过去,AsyncTask 有一个线程池,所以如果 doInBackground() 挂起,那么它不会影响其他 AsyncTask。这将 AFAIK 与 Android 2.2 或 2.3 更改为 单个线程 处理所有 AyncTask,一次一个。因此,如果您的 doInBackground() 挂起,它可能会影响下一个正在启动的 AsyncTasks,并且会在 onPreExecute() 之后立即挂起。

编辑:它从单个线程更改为多个,然后返回到单个线程: http://developer.android.com/reference/android/os/AsyncTask.html#execute%28Params...%29 "刚引入时,AsyncTasks 是在单个后台线程上串行执行的。从 DONUT 开始,这被更改为允许多个任务并行运行的线程池。在 HONEYCOMB 之后,计划将其改回单线程,避免并行执行引起的常见应用错误。”

如果您真的想要无限量地“挂”在并行中,那么不要使用 AsyncTask。使用良好的旧线程,当它们需要更新 GUI 时,触发 Runnable 以在 GUI 线程上运行:

Button knap1, knap2, knap3;
...

  Runnable r=new Runnable() {
    public void run() {
      // Do some stuff than hangs
      try { Thread.sleep(10000); } catch (InterruptedException ex) {}
      System.out.println("færdig!");

      // Update GUI thread
      Runnable r2=new Runnable() {
        public void run() {
          knap3.setText("færdig!");
        }
      };
      runOnUiThread(r2);
    }
  };
  new Thread(r).start();

(来自http://code.google.com/p/android-eksempler/source/browse/trunk/AndroidElementer/src/eks/asynkron/Asynkron1Thread.java?spec=svn109&r=109的示例)

【讨论】:

  • 你知道有什么方法可以帮助我解决这个问题吗?
  • 最好是更改您的代码,以便网络操作在一段时间后超时。它在您的 UseHttpsConnection() 和 UseHttpConnection() 中,您没有发布需要进行更改的内容。如果你使用 HttpURLConnection,那么做一个 setConnectTimeout(10000);使其在 10 秒后超时。如果您真的想要无限量地“挂”在并行中,那么不要使用 AsyncTask。使用好的旧线程,看看我上面的示例代码
  • 实际上这是我改变我的 AsyncTask 的方式 - 现在使用线程,所以谢谢你的回答!我已经做到了。
【解决方案2】:

这可能是因为您正在同步对象“Synchronization.this”。 还注意到您没有关闭您打开的光标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多