Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-异步任务未按预期更新活动_Android_Android Asynctask - Fatal编程技术网

Android-异步任务未按预期更新活动

Android-异步任务未按预期更新活动,android,android-asynctask,Android,Android Asynctask,我有一个按钮,它运行一个异步任务,从web下载一些信息,并将这些信息放入活动中的一个局部变量中,可以通过按另一个按钮查看。 此外,我还更新了UI中的一个视图,以说明同步是否正在运行或准备就绪 出于某种原因,有时onPostExecute不会按预期更新UI和局部变量,尽管有时会这样做。我使用调试器进行了检查,更新变量(handleDownloadComplete)的代码正在运行,但UI和show data按钮仍然没有正确更新。 注意:问题主要发生在连接超时时,但我仍然看到调试器的返回值是正确的——

我有一个按钮,它运行一个异步任务,从web下载一些信息,并将这些信息放入活动中的一个局部变量中,可以通过按另一个按钮查看。 此外,我还更新了UI中的一个视图,以说明同步是否正在运行或准备就绪

出于某种原因,有时onPostExecute不会按预期更新UI和局部变量,尽管有时会这样做。我使用调试器进行了检查,更新变量(handleDownloadComplete)的代码正在运行,但UI和show data按钮仍然没有正确更新。 注意:问题主要发生在连接超时时,但我仍然看到调试器的返回值是正确的——“连接超时”,但活动并没有更新

谢谢

异步任务类:

public class DownloadDataTask extends AsyncTask<String, Integer, String> {
    public interface DownloadCompleteHandler
    {
        void handleDownloadComplete(String result);
    }

    private DownloadCompleteHandler handler;


    @Override
    protected String doInBackground(String... urls) {

        try {
            return downloadUrl(urls[0]);
        } catch (IOException e) {
            return "Unable to retrieve web page. URL may be invalid.";
        }
    }

    @Override
    protected void onPostExecute(String result) {
        handler.handleDownloadComplete(result);
    }

    private String downloadUrl(String urlStr) throws IOException
    {
        InputStream is = null;
        String result = new String();

        try {
            URL url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);

            conn.connect();
            int response = conn.getResponseCode();
            is = conn.getInputStream();

            BufferedReader in = new BufferedReader(new InputStreamReader(is));
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                result += inputLine;            
            }       
        }
        catch (MalformedURLException ex) {
            result = "Malformed URL: " + urlStr;
        }
        catch (SocketTimeoutException ex) {
            result = "Connection timed out";
        }
        finally {
            if (is != null)
                is.close();
        }

        return result;
    }

    public void setHandler(DownloadCompleteHandler handler) {
        this.handler = handler;
    }   
}
编辑:我注意到我缺少
onSaveInstanceState
onRestoreInstanceState
实现,并认为这可能是原因,因为问题只在连接超时时出现,这可能会导致活动因某种原因重新启动。所以我添加了它们(也在上面的代码中),但问题仍然发生

任何人有什么想法吗?

我错了

但我认为这不是连接超时的问题。它可能是当你改变设备的方向。因为当方向改变时,活动将重新创建,并且有一个具有不同textview的新活动对象

但如果是这样的话,那么你应该尝试将android:configChanges=“orientation | keyboardHidden | screenSize”添加到你的mainfest中

这篇文章很好地描述了当前的问题:

已编辑

onSaveInstanceState只保存该活动使用的数据,而不保存视图。将重新创建视图。因为您正在通过downloader.setHandler传递活动的引用(this);因此,下载后,完整的处理程序将指向旧活动而不是新活动,textview将属于旧活动。因此,新活动没有完成下载事件


如果您确定handler.handleDownloadComplete(结果)已完成;正在调用,则这可能是唯一的问题。

您必须调用runOnUiThread以正确更新ui线程上的小部件,如下所示:

public void handleDownloadComplete(final String result)
{
     runOnUiThread(new Runnable() {
         public void run() {
             downloadResult = result;
             TextView view = (TextView)findViewById(R.id.textWebResult);
             view.setText("Ready");
             isSyncing = false;
         }    
     }); 
}

在这种情况下,控制是否会转到handleDownloadComplete()方法。?是的,根据调试器,它是,并且在运行视图的setText()方法后,GUI仍然保持不变。让我们尝试直接在onPostExecute方法中设置textview,而不使用接口。告诉我结果。同样的事情。。。为什么这很重要?这只是一个函数调用,而不是另一个线程…顺便说一句,它只在连接超时时发生。如果连接成功,它就永远不会发生。所以可能是等待15秒的结果…我想可能是这样,但我试着确保手机在整个过程中保持相同的方向,问题仍然出现。。。不管怎样,我还是要试试。好吧,这肯定和这个有关。你能再解释一下吗?既然我将信息保存在onSaveInstanceState中,为什么这不起作用?如果可以的话,我不想覆盖配置更改。事实并非如此,因为AsyncTask的onPostExecute()总是在UI线程上执行。您是否尝试将对handler.handleDownloadComplete(result)的调用从postExecute移动到downloadUrl方法?上述代码也是必需的。当超时发生时,postExecute可能由于某种原因没有调用。postExecute正在调用,我可以在调试器中看到它。我一个接一个地跟踪这些命令,发现当我运行updateview命令时,UI中什么都没有发生。
public void handleDownloadComplete(final String result)
{
     runOnUiThread(new Runnable() {
         public void run() {
             downloadResult = result;
             TextView view = (TextView)findViewById(R.id.textWebResult);
             view.setText("Ready");
             isSyncing = false;
         }    
     }); 
}