2013-06-26 31 views
1

我有一个类,我用它从我的应用程序发送数据到一个网站。有多种方法迎合不同类型的数据,我想送,代码提取物在这里:数据库从AsyncTask更新onPostExecute

public class TransmitMetrics { 
private final String request = "http://192.168.0.60/post.php"; 
private String function; 
private URL url; 
private HttpURLConnection connection; 
private String line; 
private String urlParameters; 

public void updatePhone(String device_id, String country) { 

    String make = Build.MANUFACTURER; 
    String model = Build.MODEL; 
    String sdk = Build.VERSION.SDK; 

    function = "phoneupdate"; 
    urlParameters = "function=" + function + "&device_id=" + device_id 
      + "&make=" + make + "&model=" + model + "&country=" + country 
      + "&sdk=" + sdk; 

    new sendData().execute(); 
} 

然后我有一个嵌套的AsyncTask类(送出数据),这与不能在运行的HttpURLConnection的东西交易mainUI线程,这里的部分代码:

private class sendData extends AsyncTask<Void, Void, Integer> { 
    @Override 
    protected void onPostExecute(Integer result) { 
     super.onPostExecute(result); 
        //Proposed DB stuff here based on return code 
        //stored in the result variable. 
    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 

     try { 
      url = new URL(request); 
     } catch (MalformedURLException e1) { 
      e1.printStackTrace(); 
     } 

     try { 
      connection = (HttpURLConnection) url.openConnection(); 
      connection.setDoOutput(true); 
      connection.setDoInput(true); 
      connection.setInstanceFollowRedirects(false); 
      connection.setRequestMethod("POST"); 
      connection.setRequestProperty("Content-Type", 
        "application/x-www-form-urlencoded"); 
      connection.setRequestProperty("charset", "utf-8"); 
      connection.setRequestProperty("Content-Length", 
        "" + Integer.toString(urlParameters.getBytes().length)); 
      connection.setUseCaches(false); 

      DataOutputStream wr = new DataOutputStream(
        connection.getOutputStream()); 
      wr.writeBytes(urlParameters); 
      wr.flush(); 

我没有问题的代码,它工作正常,但是,我最近一直在努力提高应用程序中加入一个数据库更新取决于响应从HttpURLConnection返回的代码。 onPostExecute()是标准方式,但我不确定是否应该开始声明数据库连接并从onPostExecute()方法内执行数据库更新。

我想要一些建议,如果有更好的方法来做到这一点,或者如果我不应该首先使用AsyncTask这种类型的功能。

回答

0

作为第一个注意事项,我相信你应该有一个单独的类来执行数据库操作,因为你的代码对于一个类来说太复杂了。它似乎已经打破Single-Responsibility Principle。我会将当前的Http操作移到一个新类中。此外,保持对URL,HttpURLConnection和参数的类引用并不安全,因为您可能在同一时间有2个正在运行的请求,并且共享这些属性会导致意外的结果。

回到你的问题,假设sendData.execute(...)在UI线程上启动,那么onPostExecute(Integer)也会在UI线程上运行。数据库操作应该在非UI线程上执行,因为您不知道数据库将有多大的“疯狂”增长。所以你可以在另一个AsyncTask上移动数据库操作 - 如果你需要数据库操作结果。否则一个简单的后台线程是绰绰有余。

+0

谢谢,这是更有意义的,我打算将HTTP位移出一个新的类,但唯一的问题是,异步任务不在onPostExecute()方法中为您提供很大的灵活性,因为它仅用于UI更新。如果我有一个单独的HTTP和数据库操作类,我可以用onPostExecute()方法调用具有有效上下文的数据库类吗? – bazza2000

+0

使用Handler/Thread类会更好吗? – bazza2000

+0

*异步任务不会为onPostExecute()方法提供很大的灵活性,因为它只能用于UI更新*您可以在onPostExecute()方法中返回自定义对象,并且您可以灵活使用。您可以创建一个自定义的'HttpResponseObject'类,其中包含响应代码,失败细节以及您需要的任何内容。如果您需要额外的灵活性,可以在UI线程上返回并评估。这足够灵活吗? – gunar

0

是的,你可以使用httpurlconnection中的responsebody。我想你不会使用json发送或接收来自服务器的数据。最好使用json格式,它有助于以对象形式获取数据或从服务器端获取数据。

0

您可以使用Aynctask执行任何执行其他操作的任务,并希望在UI上执行该操作的结果。以您的示例为例,您可以使用asyntask在onBackground方法中执行一些数据库和光标操作,并在onPostExecute方法,相同的规则可以应用于任何非UI操作。

+0

嗯,这导致我到另一个查询,然后关于通过onPostExecute()获取“上下文”,我需要将它传递到顶级类TransmitMetrics,然后从那里再次传递给嵌套的sendData类这样我可以在onPostExecute()方法中使用数据库连接。对我来说似乎有点丑陋?有没有更好的方法来做到这一点? – bazza2000

+0

您可以在您的类TransmitMetrics中创建setter getter方法,并通过构造函数在sendData asynctask中传递它。在sendData类中创建一个默认构造方法。 像“新发送数据(上下文).execute()” –