【问题标题】:right way to write code for UI and background tasks [closed]为 UI 和后台任务编写代码的正确方法 [关闭]
【发布时间】:2014-09-06 14:22:18
【问题描述】:
  1. 如何正确管理android应用程序的代码? (用于任务/UI)
  2. 如何将用户界面与代码分开? (使用类或打包)
  3. 如何从后台线程/操作 (correct way) 向用户界面添加项目? 例如,我 有表格布局。如何正确地将行添加到该 TableLayout? 根据我的需要创建自定义对象(类),然后将项目添加到对象 然后循环遍历该对象并将项目添加到 TableLayout? 传递 TableLayout 作为参考?
  4. 为数据收集创建单独的classpackage 更好? (连接到数据提供者,获取数据,显示给用户)

我四处搜索,找到了一些执行后台任务的方法。
- 首先是AsyncTaskHere 写的是AsyncTasks should ideally be used for short operations (a few seconds at the most.)
- 我找到的第二个是Handler
- 有没有其他正确的方法来做后台任务?

Witch 方式对于从 WEB 服务收集数据是否正确(可能会有一些延迟和滞后)? 如果使用Handler 那么如何将数据传递给 UI 线程?在大多数情况下,我对第 3 个问题感兴趣。

谢谢。

【问题讨论】:

  • 单独提出每个问题。只有这样,您才能期待详细的答案。
  • 基本上所有4个问题都是相互关联的。将所有代码写入一个文件/类,或拆分它。一般的问题是 - 如何以correct 方式做到这一点。
  • 但是你应该把它分成一个确切的问题,每个问题都有正确的上下文。此外,没有“正确的方法”。有很多,我们只能从我们的角度为您提供最好的建议......

标签: java android


【解决方案1】:

有很多方法可以设计Android 应用程序的结构。你的问题很笼统,所以我的回答也是。

要构建您的项目,您可以使用MVC 模式,该模式可以轻松地与Android 一起使用:

  • 模型:主要保存数据,如列表、数组、字符串等
  • 控制器:处理模型数据,运行逻辑
  • 视图:用户界面,可以显示来自模型的数据和/或从控制器运行逻辑

一般无法回答是否与包或类分开的问题。两者都适用于许多情况。在我看来,以下结构作为一个简单的例子会很有用:

  • [包]查看:
    • Activty1.java
    • Activty2.java
  • 【包装】型号:
    • Activty1DataModel.java
    • Activty2DataModel.java
  • [包]控制器:
    • Activty1Logic.java
    • Activty2Logic.java

较重的任务应该在 Android 上的 AsyncTaks 上运行,而不是在 UIThread 上运行(例如,因为 GUI 冻结)。 AsyncTask 在新的单独线程中运行操作。 onPostExecute 方法在任务完成后执行并运行在 UI 线程上,因此您可以直接从这里与视图交互。

对于真正长时间运行的任务,您应该使用background services

当您想从另一个线程与 UI 交互时,您必须在 UI 线程上显式运行操作,例如像这样:

MainActivity.this.runOnUiThread(new Runnable() {
    public void run() {
       Log.d("UI thread", "I am the UI thread");
   }
});

与 UI 交互的另一种方式是使用 Interfaces / Listeners

要从 Web 服务收集数据,您可以使用带有 AsyncTask 的 http 客户端,但不能从 UI 线程运行网络操作(会导致异常)。这是example

下次请在不同的帖子中提出几个问题,而不是一个问题。

【讨论】:

    【解决方案2】:

    1)。问题不清楚。如果你是这个意思,你会为每个班级使用自己的.java 文件。

    2)。使用多个包。

    3)。我想说从后台更新 UI 的最佳方法是使用接口。下载图片示例(使用HttpClient):

      public class AsyncImageSetter extends AsyncTask<String, Void, Bitmap> {
    
    private onImageLoaderListener listener;
    private String msg, server;
    
    public AsyncImageSetter(onImageLoaderListener listener) {
        this.listener = listener;
    }
    /* the onImageLoaded callback will be invoked on UI thread */
    public interface onImageLoaderListener {
        void onImageLoaded(Bitmap bmp, String response);
    }
    
    @Override
    protected Bitmap doInBackground(String... params) {
        HttpParams hparams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(10000);
        HttpConnectionParams.setSoTimeout(10000);
        server = params[0];
        HttpGet get = new HttpGet(server);
        try {
            DefaultHttpClient client = new DefaultHttpClient(hparams));
            HttpResponse response = null;
            /** set cookies if you need it */
            CookieStore store = client.getCookieStore();
            HttpContext ctx = new BasicHttpContext();
            store.addCookie(yourSavedCookieObject);
            ctx.setAttribute(ClientContext.COOKIE_STORE, store);
            response = client.execute(get);
            msg = response.getStatusLine().toString();
            HttpEntity responseEntity = response.getEntity();
            BufferedHttpEntity httpEntity = null;
            try {
                httpEntity = new BufferedHttpEntity(responseEntity);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            InputStream imageStream = null;
            try {
                imageStream = httpEntity.getContent();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return BitmapFactory.decodeStream(imageStream);
    
        } catch (Exception ex) {
            ex.printStackTrace();
            //error handling
            return null;
        }
    }
    
     /* use this method if your backend sets some pre-defined messages. /*
     /* In my case that would be "Warning */
    private void checkResponse(HttpResponse response) {
        Header[] headers = response.getAllHeaders();
        final String target = "Warning";
        for (Header h : headers) {
            if (h.getName().equalsIgnoreCase(target)) {
                msg = h.getValue();
            } else {
                continue;
            }
        }
    
    }
    
    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        /* now this callback is invoked on UI thread */
        /* if everything went without errors, you'll get an image and "HTTP 200 OK" in msg */
        if (listener != null) {
            listener.onImageLoaded(result, msg);
        }
    
     }
    
    }
    

    您需要传递 new onImageLoaderListener 并覆盖 onImageLoaded 回调,您将在其中获取图像和服务器消息。

    4)。您基本上会使用自己的包,其中包含在后台执行某些工作的类

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-20
      • 1970-01-01
      • 1970-01-01
      • 2021-05-16
      • 1970-01-01
      • 2010-11-22
      相关资源
      最近更新 更多