Android:从URL读取文件会引发HttpURLConnectionImpl错误

时间:2018-08-12 04:27:44

标签: java android url

我已经使用Android Studio创建了一个android应用程序,该应用程序试图检查是否存在该应用程序使用的文件的更新版本,该文件存储在资产目录中。 我已经检查了文件的可用性和可访问性,但是由于无法共享文件位置,因此在此示例中,我将使用以下文本文件:http://www.w3.org/TR/PNG/iso_8859-1.txt

我谨记要在代码中包含以下内容:

1-在清单文件.xml中添加uses-permissions,如下所示:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />    

2-创建了AsyncTask以在后台执行文件读取:

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class CheckUpdate extends AsyncTask<Void,Void,Boolean>
{

String filename = "http://www.w3.org/TR/PNG/iso_8859-1.txt";

private Context ctx;

public CheckUpdate(Context myContext) {
    this.ctx = myContext;
    doInBackground();

}

@Override
protected Boolean doInBackground(Void... voids) {
    try {
        URL url = new URL(filename);
        File LocalFile = new File("file:///android_asset/test.txt");

        HttpURLConnection ucon = (HttpURLConnection) url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
ucon.setDoInput(true);
        ucon.setDoOutput(true);
        ucon.connect();
        if (ucon.getResponseCode() == 200) {
            InputStream isURL = ucon.getInputStream();
            BufferedInputStream inStream = new BufferedInputStream(isURL);

            long LocalFileModifiedDate = LocalFile.lastModified();
            long ExFileModifiedDate = ucon.getLastModified();

            if (LocalFile.exists()) {
                LocalFile.delete();
            }

            if (LocalFileModifiedDate < ExFileModifiedDate) {
                LocalFile.createNewFile();

                FileOutputStream outStream = new FileOutputStream(LocalFile);
                byte[] buff = new byte[5 * 1024];

                int len;
                while ((len = inStream.read(buff)) != -1) {
                    outStream.write(buff, 0, len);
                }

                outStream.flush();
                outStream.close();
            }
            inStream.close();
        } else {
            return false;
        }
    }catch (MalformedURLException e1) {
        e1.printStackTrace();
        return false;
    } catch (IOException e1) {
        e1.printStackTrace();
        return false;
    }catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }

        return true;
    }

}    

3-在MainActivity中检查无线连接:

ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    @SuppressLint("MissingPermission") NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

    if (mWifi.isConnected()) {
        CheckUpdate checkUpdate = new CheckUpdate(getApplicationContext());
    }

但不幸的是,我收到以下错误消息:

W/System.err: android.os.NetworkOnMainThreadException
              at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
W/System.err:     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:117)
W/System.err:     at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
              at java.net.InetAddress.getAllByName(InetAddress.java:1154)
              at com.android.okhttp.Dns$1.lookup(Dns.java:39)
W/System.err:     at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175)
W/System.err:     at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141)
              at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83)
W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)
              at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
 W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
              at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
              at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
 W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
              at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
 W/System.err:     at **com.Project.CheckUpdate.doInBackground(CheckUpdate.java:40)**
              at com.Project.CheckUpdate.<init>(CheckUpdate.java:25)
 W/System.err:     at com.Project.MainActivity.onCreate(MainActivity.java:124)
              at android.app.Activity.performCreate(Activity.java:7136)
              at android.app.Activity.performCreate(Activity.java:7127)
 W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
 W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
 W/System.err:     at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
              at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
              at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
 W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
              at android.os.Handler.dispatchMessage(Handler.java:106)
              at android.os.Looper.loop(Looper.java:193)
              at android.app.ActivityThread.main(ActivityThread.java:6669)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
              at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)    

在此先感谢...

1 个答案:

答案 0 :(得分:0)

您不应在 CheckUpdate 类的构造函数中调用 doInBackground()方法。您正在主线程中调用构造函数,因此 doInBackground()也在主线程中调用。它导致 NetworkOnMainThreadException 。 以下是一些如何使用AsyncTask的链接:linklink

您需要像这样重构 CheckUpdate.java 的构造函数:

public CheckUpdate(Context myContext) {
    this.ctx = myContext;
}

并像这样使用它:

if (mWifi.isConnected()) {
    CheckUpdate checkUpdate = new CheckUpdate(getApplicationContext());
    checkUpdate.execute();
}