从 url 下载 pdf 文件在主线程上工作,但是当我使用 asynctask 时出错
Posted
技术标签:
【中文标题】从 url 下载 pdf 文件在主线程上工作,但是当我使用 asynctask 时出错【英文标题】:Downloading a pdf file from url works on the main thread but is giving errors when I use asynctask 【发布时间】:2019-10-27 02:11:01 【问题描述】:我正在编写一个程序来将 pdf 文件从 url 下载为字节格式,然后将其显示在 android 的 PdfViewer 上。但是下载需要一些时间,我想使用 asynctask 在单独的线程上执行此操作。 代码在没有 asynctask 的情况下运行良好,但在我使用 asynctask 时会出错。
loadBookPdf.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
AsyncTask<String, Void, byte[]> task = new AsyncTask<String,
Void, byte[]>()
ProgressBar bar;
@Override
protected void onPreExecute()
bar = findViewById(R.id.progressBar);
bar.setVisibility(View.VISIBLE);
@Override
protected byte[] doInBackground(String... strings)
Log.e("thread", "success?");
String urlString = strings[0];
byte[] bookByte = getFile(urlString);
Log.e("thread", "success");
return bookByte;
@Override
protected void onPostExecute(byte[] bytes)
fileReader = bytes;
bar.setVisibility(View.GONE);
;
task.execute(BookBriefInfo.textUrl);
// fileReader = getFile(BookBriefInfo.textUrl);
Intent intent = new Intent(BookBriefInfo.this,
BookPdfReader.class);
startActivity(intent);
finish();
);
文件阅读器代码:
private byte[] getFile(String pdfUrl)
//TODO send translation URL from cloudLibraryAdaptor
URL url;
HttpURLConnection c;
byte[] bytes = null;
try
url = new URL(pdfUrl);
c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.connect();
InputStream is = c.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
for (int readNum; (readNum = is.read(buf)) != -1; )
bos.write(buf, 0, readNum);
bytes = bos.toByteArray();
// fileReader = bytes;
catch (IOException e)
e.printStackTrace();
return bytes;
我得到的错误:
A/zygote: java_vm_ext.cc:504] JNI DETECTED ERROR IN APPLICATION: jarray
was NULL
java_vm_ext.cc:504] in call to GetByteArrayElements
java_vm_ext.cc:504] from long com.shockwave.pdfium.PdfiumCore.nativeOpenMemDocument(byte[], java.lang.String)
java_vm_ext.cc:504] "AsyncTask #2" prio=5 tid=26 Runnable
java_vm_ext.cc:504] | group="main" sCount=0 dsCount=0 flags=0 obj=0x1322fec0 self=0xa401dc00
java_vm_ext.cc:504] | sysTid=8528 nice=10 cgrp=default sched=0/0 handle=0x8e10b970
java_vm_ext.cc:504] | state=R schedstat=( 12742370 18637590 15 ) utm=1 stm=0 core=1 HZ=100
java_vm_ext.cc:504] | stack=0x8e009000-0x8e00b000 stackSize=1038KB
A/zygote: java_vm_ext.cc:504] |持有 mutexes="mutator lock"(共享持有)
【问题讨论】:
能否提供您的错误日志。 我怀疑您是否在主线程上成功执行此操作,因为如果您尝试,Android 会抛出 NetworkOnMainThreadException。 【参考方案1】:为什么不使用 Volley 来请求? 这段代码现在正在一个真正的应用程序上运行:
RequestQueue myQueue= Volley.newRequestQueue(this);
InputStreamVolleyRequest request = new InputStreamVolleyRequest(Request.Method.GET, my_url,
new Response.Listener<byte[]>()
@Override
public void onResponse(byte[] response)
try
if (response != null)
String path = "your_path";
String filename = "your_filename";
FileOutputStream outputStream;
outputStream = openFileOutput(path + "/" + filename, Context.MODE_PRIVATE);
outputStream.write(response);
outputStream.close();
catch (Exception e)
// TODO Auto-generated catch block
Log.d("KEY_ERROR", "UNABLE TO DOWNLOAD FILE");
e.printStackTrace();
, new Response.ErrorListener()
@Override
public void onErrorResponse(VolleyError error)
Log.d("Error response", error.toString());
)
// httpbin.org needs proper accept headers
@Override
public Map<String, String> getHeaders() throws AuthFailureError
Map<String, String> params = new HashMap<String, String>();
//params.put("Content-Type", "application/pdf");
return params;
;
request.setRetryPolicy((new DefaultRetryPolicy(60 * 1000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)));
myQueue.add(request);
【讨论】:
以上是关于从 url 下载 pdf 文件在主线程上工作,但是当我使用 asynctask 时出错的主要内容,如果未能解决你的问题,请参考以下文章
尝试使用Ajax从远程服务器下载文件,而Codeigniter无法正常工作
如何从 Angular 5 中的 url 下载 pdf 文件