【问题标题】:Correct use of AsyncTasks and handle Objects needed by a View and Activity正确使用 AsyncTasks 并处理 View 和 Activity 所需的 Objects
【发布时间】:2014-04-01 15:17:13
【问题描述】:

所以我目前正在编写一个应用程序,并且有几个关于如何处理 AsyncTasks 的问题。 我尽可能详细地描述我的问题。我有以下课程:

  1. MainActivity - 此 Activity 仅执行 setContentView(R.layout.myLayout) 和 创建我的 CustomLocationListener 的对象。布局包含一个自定义视图和一个ProgressBar
  2. CustomLocationListener - 这基本上只是一个实现LocationListener 并具有默认LocationListener 方法的类。除此之外,我还编写了一个方法来检查哪些提供者可以优先使用NETWORK_PROVIDER
  3. Display - 这只是一个辅助类。我只用它来获取显示指标来计算一些东西。
  4. MyCustomView - 这个类扩展了View 类。它还有一个Display 类型的属性(我自己的类)。

现在您应该知道对我的代码很重要的所有内容了。好吧,我现在的问题是,如何处理 AsyncTasks,因为这是 App 应该经过的步骤:

  1. 获取用户设备的当前位置
  2. 对数据库服务器 (mysql) 执行一些查询并将它们保存为非持久性(数据由城市名称组成)
  3. 计算用户位置与数据库中城市的距离
  4. 做一些其他的计算来确定在屏幕上绘制的位置
  5. 画出一切

最重要的是,我想实现一个进度条,它应该是活动的,直到所有计算完成并且绘图阶段开始。 所以,我有点困惑在哪里编码什么。我的意思是,两个计算(第 3 步和第 4 步)都必须相互了解。第4步的计算需要第3步的计算结果。而且我的Activity类也应该知道计算的状态,因为我必须在开始绘制时使ProgressBar不可见。

我希望我足够详细,感谢您的帮助!

【问题讨论】:

  • 我可以在 Activity 类中执行所有需要的线程,并且在完成所有计算之后,我可以使 ProgressBar 不可见。但是我怎样才能开始画画呢?我的意思是,当我打开 Activity 时,onDraw() 会立即启动。如果计算完成,我可以使用 If-Else-Block 来检查布尔值。但是如何使视图类之外的线程中的视图无效?

标签: java android mysql android-asynctask


【解决方案1】:

好吧,您可以从AsyncTask 文档中收集到这些信息:

当一个异步任务被执行时,任务会经过4个步骤:

  1. onPreExecute(),在任务执行之前在 UI 线程上调用。此步骤通常用于设置任务,例如 通过在用户界面中显示进度条。

  2. doInBackground(Params...),在 onPreExecute() 完成执行后立即在后台线程上调用。这一步使用 执行可能需要很长时间的后台计算。这 异步任务的参数传递给这一步。这 此步骤必须返回计算结果,并将 回到最后一步。这一步也可以使用 publishProgress(Progress...) 发布一个或多个进度单位。 这些值在 UI 线程上发布,在 onProgressUpdate(Progress...) 步骤。

  3. onProgressUpdate(Progress...),在调用 publishProgress(Progress...) 后在 UI 线程上调用。执行时间为 不明确的。此方法用于显示任何形式的进度 后台计算仍在执行时的用户界面。 例如,它可以用于动画进度条或显示登录 一个文本字段。

  4. onPostExecute(Result),在后台计算完成后在 UI 线程上调用。背景的结果 计算作为参数传递给这一步。

所以我建议您使用两个 AsyncTask 在 doInBackground(Params...) 方法中执行您的地理和服务器(每个一个)工作,并在 onPostExecute(Result) 方法中将值返回给您的 MainActivity。此外,使用 onProgressUpdate(Progress..) 方法让您的 MainActivity 了解进度。

完成后,如果它们明显停止 UI 线程,您可以选择使用另一个 AsyncTask 进行计算。使用相同的执行方法。

当这一切都完成后,你就可以开始绘制视图了……(我想这就是你的意思)

在您开始计算“正在加载...”或其他任何内容之前,请先加载默认视图。准备好另一个不可见的视图,以便在您准备好显示计算的内容时使用,并在准备好绘制时将其设置为可见。

【讨论】:

  • 感谢您的回答!我认为这会奏效。到目前为止,我已经实现了一个 AsyncTask 来获取当前位置。我只是对自定义视图的可见性有问题。即使我将 xml 文件中的可见性设置为“已消失”,它仍然可见。
  • 嗯。在您的自定义视图中,您是否覆盖了父类方法“setVisibility(...)”而不是调用“super.setVisibility(...)”?
  • 不,我试过了,但没用……我现在尝试了别的方法。我在我的活动中创建了一个视图的引用,并在我的 AsyncTask 中创建了一个视图的引用。 AsyncTask的构造函数用Activity中View的引用来初始化他对View的引用。然后我尝试在我的 onPostExecute() 方法中的引用上调用 postInvalidate(),但我仍然得到 NullPointerException。 ://
  • 因此,您创建了“customView”类并通过活动的 xml 布局将其添加到活动中。现在,您可以使用 ...CustomView cv = (CustomView)findViewById(R.id.customViewId) 在活动中获取对该视图的引用。这对吗?
  • 没错。我不知道为什么这会引发 NullPointerException。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2010-09-15
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多