为UI和后台任务编写代码的正确方法

时间:2014-07-16 07:06:12

标签: java android

  1. 如何正确管理Android应用程序的代码? (对于任务/ UI)
  2. 如何将用户界面与代码分开? (使用课程或打包)
  3. 如何从后台线程/操作(correct way)向用户界面添加项目?例如,i 有TableLayout。如何正确地向TableLayout添加行? 根据我的需要创建自定义对象(类),然后将项添加到对象 然后遍历该对象并将项添加到TableLayout? 将TableLayout作为参考传递?
  4. 最好是为数据收集创建单独的classpackage? (连接到数据提供者,获取数据,显示给用户)
  5. 我四处寻找并找到了一些办法来完成后台任务   - 首先是AsyncTaskHere写的是AsyncTasks should ideally be used for short operations (a few seconds at the most.)   - 我发现的第二个是Handler   - 还有其他正确的方法来完成后台任务吗?

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

    感谢。

2 个答案:

答案 0 :(得分:1)

设计Android应用的结构有很多种方法。你的问题非常笼统,所以我的答案也是。

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

  • 模型:主要保存数据,如列表,数组,字符串等
  • 控制器:使用模型数据,运行逻辑
  • 查看:userinterface,可以显示来自模型的数据和/或来自控制器的运行逻辑

与包裹或类别分开的问题通常无法回答。两者都适用于许多情况。在我看来,一个简单示例的以下结构将非常有用:

  • [包]视图:
    • Activty1.java
    • Activty2.java
  • [包装]型号:
    • Activty1DataModel.java
    • Activty2DataModel.java
  • [包]控制器:
    • Activty1Logic.java
    • Activty2Logic.java

较重的任务应该在Android AsyncTask而不是UIThread上运行(例如因为GUI冻结)。 onPostExecute在新的单独线程中运行操作。 MainActivity.this.runOnUiThread(new Runnable() { public void run() { Log.d("UI thread", "I am the UI thread"); } }); 方法在完成任务后执行并在UI线程上运行,因此您可以直接从此处与视图进行交互。

对于实际长时间运行的任务,您应该使用AsyncTaks

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

Interfaces

与UI互动的另一种方法是使用Listeners / AsyncTask

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

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

答案 1 :(得分:0)

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)。您基本上使用自己的包,其中包含在后台执行某些工作的类