Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/197.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 解压服务中的.zip文件会使应用程序冻结,直到解压完成,为什么?_Java_Android_Service_Android Asynctask_Zip - Fatal编程技术网

Java 解压服务中的.zip文件会使应用程序冻结,直到解压完成,为什么?

Java 解压服务中的.zip文件会使应用程序冻结,直到解压完成,为什么?,java,android,service,android-asynctask,zip,Java,Android,Service,Android Asynctask,Zip,我实现了一个异步任务的代码,它工作得很好,但如果用户退出应用程序,它会很快被杀死,所以我决定用一个服务来尝试它,它工作得很好,但它会使应用程序冻结 这是我的减压课: public class Decompress { private String _zipFile; private String _location; ZipEntry ze = null; public Decompress(String zipFile, String location

我实现了一个异步任务的代码,它工作得很好,但如果用户退出应用程序,它会很快被杀死,所以我决定用一个服务来尝试它,它工作得很好,但它会使应用程序冻结

这是我的减压课:

    public class Decompress {
    private String _zipFile;
    private String _location;
    ZipEntry ze = null;

    public Decompress(String zipFile, String location) {
        _zipFile = zipFile;
        _location = location;

        _dirChecker("");
    }

    public void unzip() {
        try  {
            FileInputStream fin = new FileInputStream(_zipFile);
            ZipInputStream zin = new ZipInputStream(fin);
            while ((ze = zin.getNextEntry()) != null) {
                //Log.v("Decompress", "Unzipping " + ze.getName()); 

                if(ze.isDirectory()) {
                    _dirChecker(ze.getName());
                } else {
                    FileOutputStream fout = new FileOutputStream(_location + ze.getName());
                    for (int c = zin.read(); c != -1; c = zin.read()) {
                        fout.write(c);
                    }

                    zin.closeEntry();
                    fout.close();
                } 

            }
            zin.close();
        } catch(Exception e) {
            Log.e("Decompress", "unzip", e);
        }

    }

    private void _dirChecker(String dir) {
        File f = new File(_location + dir);

        if(!f.isDirectory()) {
            f.mkdirs();
        }
    }
}
这是我的解压服务电话:

@Override
public void onStart(Intent intent, int startid)
{

    try
    {
        zipFile = intent.getStringExtra("zipFile");
        zipLocation = intent.getStringExtra("unzipLocation");
        String fileS = intent.getStringExtra("file");
        file = new File(fileS);
        fin = new FileInputStream(zipFile); 
        zin = new ZipInputStream(fin);

        while (zin.getNextEntry() != null) {
            numFiles++;
        }
    }
    catch (FileNotFoundException e)
    {}
    catch (IOException e)
    {}

    d = new Decompress(zipFile, zipLocation);
    d.unzip();

}
现在,我使用异步任务调用它:

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

        d.unzip();

        return null;
    }
现在我的问题是,为什么使用async tsk,我的应用程序不会冻结,它会不断解压,让我用一个按钮取消,但使用服务,它会使应用程序滞后?我甚至收到一条消息说我的应用程序没有响应,你想关闭它吗

编辑:我的启动服务呼叫

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

        Intent intent = new Intent(DownloadFiles.this, MyService.class);
        String unzipLocation = Environment.getExternalStorageDirectory().toString()+"/Android/data/";
        String zipFile = Environment.getExternalStorageDirectory().toString()+"/Android/data/test.zip"; 
        intent.putExtra("zipFile", zipFile);
        intent.putExtra("unzipLocation", unzipLocation);
        intent.putExtra("file", Environment.getExternalStorageDirectory().toString()+"/Android/data/");
        startService(intent);

        try {
            FileInputStream fin = new FileInputStream(zipFile); 
            ZipInputStream zin = new ZipInputStream(fin);

            while (zin.getNextEntry() != null) {
                 numFiles++;
                }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

服务也在UI(主)线程中运行,因此您也需要在那里实现异步任务或独立线程方法

什么是服务?

服务不是线程。它本身并不是一种脱离主线程工作的方法(以避免应用程序不响应错误)

编辑:请注意,如果从后台线程启动服务,该服务仍在主线程中运行。照此如此。正如文件所说,这应该是有道理的:

当实际创建服务组件时,对于以下任一项 因此,系统实际上所做的只是实例化 组件并调用其onCreate()和任何其他适当的回调 在主线程上。由服务来实现这些功能 适当的行为,例如创建次线程,其中 它做它的工作


这最终意味着您应该始终在服务中实现单独的异步任务/线程方法,无论您如何启动服务。

服务也运行在UI(主)线程中,因此您也需要在那里实现异步任务或单独的线程方法

什么是服务?

服务不是线程。它本身并不是一种脱离主线程工作的方法(以避免应用程序不响应错误)

编辑:请注意,如果从后台线程启动服务,该服务仍在主线程中运行。照此如此。正如文件所说,这应该是有道理的:

当实际创建服务组件时,对于以下任一项 因此,系统实际上所做的只是实例化 组件并调用其onCreate()和任何其他适当的回调 在主线程上。由服务来实现这些功能 适当的行为,例如创建次线程,其中 它做它的工作


这最终意味着您应该始终在服务中实现单独的AsyncTask/线程方法,无论您如何启动服务。

如果您不需要AsyncTask的
onPreExecute()
onPostExecute()
方法,请尝试在单独的后台线程中运行它,但是仍然存在操作阻塞UI线程的问题

Thread t = new Thread() {
    public void run() {
        d = new Decompress(zipFile, zipLocation);
        d.unzip();
    }
};
t.start();

仅仅从后台线程启动服务并不意味着它将从主UI线程启动。这是其启动的默认设置,您必须在服务中创建一个新线程来绕过它。

如果您不需要AsyncTask的
onPreExecute()
onPostExecute()
方法,请尝试在单独的后台线程中运行它,但该操作仍然会阻塞UI线程

Thread t = new Thread() {
    public void run() {
        d = new Decompress(zipFile, zipLocation);
        d.unzip();
    }
};
t.start();
仅仅从后台线程启动服务并不意味着它将从主UI线程启动。这是它的默认开始,您必须在服务中创建一个新线程来绕过它。

在a--C点上展开: 您需要创建后台线程来从服务内部解压文件,因为服务是在主线程上创建和运行的,无论您是否在另一个线程中启动它

基本上,您需要在服务中执行与在服务之外完全相同的操作(即,将'unzip'调用放在AsyncTask中,然后执行任务)

(增编) 使用服务的目的不是创建单独的线程,而是将耗时的处理从基于UI的应用程序中分离出来。这意味着用户界面可以被操作系统破坏,资源可以被恢复,而服务仍然在运行。 因此,决定是否在应用程序本身中使用异步任务(或线程)还是在服务中使用异步任务(或线程)实际上是决定该操作是否应独立于应用程序接口继续。使用TitaniumBackup还原应用程序就是一个很好的例子:一旦开始还原,就不再需要应用程序UI了。

从--C的角度展开: 您需要创建后台线程来从服务内部解压文件,因为服务是在主线程上创建和运行的,无论您是否在另一个线程中启动它

基本上,您需要在服务中执行与在服务之外完全相同的操作(即,将'unzip'调用放在AsyncTask中,然后执行任务)

(增编) 使用服务的目的不是创建单独的线程,而是将耗时的处理从基于UI的应用程序中分离出来。这意味着用户界面可以被操作系统破坏,资源可以被恢复,而服务仍然在运行。
因此,决定是否在应用程序本身中使用异步任务(或线程)还是在服务中使用异步任务(或线程)实际上是决定该操作是否应独立于应用程序接口继续。使用TitaniumBackup还原应用程序就是一个很好的例子:一旦开始还原,就不再需要应用程序UI。

我在同步任务中添加了服务调用,很抱歉忘记添加它。将编辑我的作品。@RotaryHeart我更新了我的答案。长话短说,这项服务主要是在运行