2010-02-20 141 views
2

我的应用程序执行以下操作:AsyncTask服务无法访问

Activity1启动Activity2。
Acitivity2启动服务。
服务使用AsyncTask来下载文件。

在我的AsyncTask有一段这样的代码:

while ((status == 0)) { 

      byte buffer[]; 
      if (size - downloaded > MAX_BUFFER_SIZE) { 
       buffer = new byte[MAX_BUFFER_SIZE]; 
      } else { 
       buffer = new byte[size - downloaded]; 
      } 

      int read = stream.read(buffer); 
      if (read == -1) 
       break; 

      file.write(buffer, 0, read); 
      downloaded += read; 

    } 

一切工作像预期。随着status变量,我可以启动和停止我的下载取决于它的值。

但是,当我关闭Activity2并重新启动它(服务继续运行)时,我无法停止下载,这意味着变量status未被正确读取。我检查了变量,值是确定的,但Asynctask无法识别它。

我该如何重新控制我的AsyncTask?

我做了一些更多的测试,但这次有一个线程,以确保它不是我如何处理AsyncTask失败。我这样做:

Activity2启动服务(我没有在这里更改任何代码)。 服务创建一个Download对象使用线程下载文件的内容。

的结构是这样的:

in the Service 
private Download dl = new Download(); 

private final DMInterface.Stub mBinder = new DMInterface.Stub() { 

    public void downloadFile() throws DeadObjectException { 
     try { 
      dl.start(url) // This starts a thread and the download 

     } catch (IndexOutOfBoundsException e) { 
      Log.e(getString(R.string.app_name), e.getMessage()); 
     } 
    } 

    public void stop() throws DeadObjectException { 
     dl.cancel(); //This stops the download 
    } 

}; 

再次,一切正常,直到我从服务断开连接。为什么我只能在不断开服务的情况下控制线程?

这里是我开始/服务绑定到活性2(只有他们重要的部分)的代码:

public class Activity2 extends ListActivity { 

    private DMInterface dmInterface; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     this.bindService(new Intent(Activity2.this, DMService.class), mConnection, Context.BIND_AUTO_CREATE); 
    } 

    private ServiceConnection mConnection = new ServiceConnection() { 
     public void onServiceConnected(ComponentName className, IBinder service) { 
      dmInterface = DMInterface.Stub.asInterface(service); 
      //do some stuff 

     } 

     public void onServiceDisconnected(ComponentName className) { 
      dmInterface = null; 
     } 
    }; 
} 

有两种情况。在第一个中,我在第二个中得到一个错误(但没有其他事情发生)。 当发生错误取决于,我在哪里初始化线程例如启动线程的对象。

方案1:

当我做以上等中描述的,我没有得到任何错误,但没有任何反应。

方案2:

在服务:

private Download dl; 

private final DMInterface.Stub mBinder = new DMInterface.Stub() { 

    public void downloadFile() throws DeadObjectException { 
     try { 
      dl = new Download(); 
      dl.start(url) // This starts a thread and the download 

     } catch (IndexOutOfBoundsException e) { 
      Log.e(getString(R.string.app_name), e.getMessage()); 
     } 
    } 

    public void stop() throws DeadObjectException { 
     dl.cancel(); //This stops the download 
    } 

}; 

当我尝试达到服务的其他部分(设置变量或类似的东西),一切工作正常。

+0

这是关于状态变量的范围。您是否尝试将其设置为静态以查看该服务如何处理它。 – Steve 2010-02-20 18:29:18

+0

嘿史蒂夫,那可能,我不知道。我的应用程序是这样构造的:Activity2 - > Service(这里我定义变量) - > AsyncTask。就像我说的,一切正常,直到我断开服务。如果您需要更多代码,请告诉我。 – Andy 2010-02-21 13:44:05

+0

嘿,它再次。我对主帖进行了编辑,请再看一遍。谢谢。 – Andy 2010-02-22 15:06:43

回答

1

A Service生活在自己的世界中,作为一项服务,它远离您的程序的其余部分。 A Binder可用于与您的服务进行通信。通过使用setStatus方法定义aidl接口,您可以将状态传达给服务。

+0

更改从本地来源到网络来源的超链接。 =) – 2010-02-21 12:41:06

+0

嗨,雷内,thx为你回答。我知道一个服务的工作原理(一般而言),并且它也适用于我,直到我关闭了Aktivity2。然后,我无法正确重新连接到服务中的AsyncTask,但服务仍在运行。我开始在服务中下载保持活动。如果我保持活动打开,我可以使用线程,所以我认为重新连接到服务(AsyncTask)无法正常工作,但我不知道究竟出了什么问题。 – Andy 2010-02-21 13:38:48