从被调用方传递的参数,但在方法定义中为 null



我基本上是在尝试创建一个解压缩函数。我在下面的块中使用参数调用了该函数:

UnzipUtility unzipUtility = new UnzipUtility();
try {
unzipUtility.unzip(localFilePath, parentPath);
} catch (IOException e) {
e.printStackTrace();
}

该方法的定义是在UnzipUtility类中,其代码如下:

public void unzip(String zipFilePath, String destDirectory) throws IOException {
File destDir = new File(destDirectory);
if (!destDir.exists()) {
destDir.mkdir();
}
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
ZipEntry entry = zipIn.getNextEntry();
// iterates over entries in the zip file
while (entry != null) {
String filePath = destDirectory + File.separator + entry.getName();
if (!entry.isDirectory()) {
// if the entry is a file, extracts it
extractFile(zipIn, filePath);
} else {
// if the entry is a directory, make the directory
File dir = new File(filePath);
dir.mkdir();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
}

但在运行时,尽管参数在主类中正确传递,但这些值在解压缩方法中显示为 null。

请帮忙

主类如下:

package com.example.sftpconnection;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;

//import java.io.BufferedOutputStream;
import java.io.File;
//import java.io.FileOutputStream;
import java.io.IOException;
//import java.io.OutputStream;
import java.util.List;
import com.example.sftpconnection.UnzipUtility;
public class SFTPActivity extends AppCompatActivity {
private String fileName = "1234.zip";
private String localFilePath;
private String parentPath;
@SuppressLint("StaticFieldLeak")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sftp);

new AsyncTask<Void, Void, List<String>>() {
@Override
protected List<String> doInBackground(Void... params) {
try {
Downloader(fileName);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.execute();
UnzipUtility unzipUtility = new UnzipUtility();
try {
unzipUtility.unzip(localFilePath, parentPath);
} catch (IOException e) {
e.printStackTrace();
}
}
public void Downloader(String fileName) {
String user = "1234";
String pass = "1234";
String host = "1234";
int portNum = 22;
JSch jsch = new JSch();
Session session;
try {
session = jsch.getSession(user,host,portNum);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(pass);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;

File localFile = File.createTempFile("1234",".zip");
sftpChannel.get(fileName,localFile.getAbsolutePath());
//sftpChannel.get(fileName);
Log.d(fileName, " has been downloaded");
sftpChannel.exit();
session.disconnect();
localFilePath = localFile.getAbsolutePath();
parentPath = localFile.getParent();
} catch (JSchException | IOException | SftpException e) {
e.printStackTrace();
}
}

}

出于安全原因,我编辑了数据字段。

可以剪掉以下行:

UnzipUtility unzipUtility = new UnzipUtility();
try {
unzipUtility.unzip(localFilePath, parentPath);
} catch (IOException e) {
e.printStackTrace();
}

粘贴在类 SFTPActivity中的以下行下方:

Downloader(fileName); 

方法doInBackground. 实际上,该方法doInBackground()与运行该方法onCreate的线程不同的线程中运行。您尝试在方法Downloader(fileName)可以完成其工作之前使用这些变量。这就是为什么您在变量中看到空值的原因:localFilePathparentPath

您的代码不起作用的原因是因为在运行此行时:

unzipUtility.unzip(localFilePath, parentPath);

尚未设置变量localFilePathparentPath

你可能会争辩说它们是在方法Downloader中设置的,该方法在unzip行之前调用。不幸的是,事实并非如此。在这种情况下,代码执行不是线性的,因为您使用的是AsyncTask。异步任务中的内容与它后面的行同时运行。

在调用unzipUtility.unzip之前,下载调用不会完成,因为与创建新的UnzipUtility对象相比,下载需要大量时间。

这就是localFilePathparentPath为空的原因。

解决此问题的一种方法是将解压缩逻辑也移动到异步任务中:

new AsyncTask<Void, Void, List<String>>() {
@Override
protected List<String> doInBackground(Void... params) {
try {
Downloader(fileName);
UnzipUtility unzipUtility = new UnzipUtility();
unzipUtility.unzip(localFilePath, parentPath);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.execute();

另一种方法是覆盖AsyncTask中的onPostExecute

new AsyncTask<Void, Void, List<String>>() {
// doInBackground goes here...
@Override
protected void onPostExecute(Long result) {
try {
UnzipUtility unzipUtility = new UnzipUtility();
unzipUtility.unzip(localFilePath, parentPath);
} catch (Exception e) {
e.printStackTrace();
}
}
}

最新更新