将url加载到String变量

时间:2015-10-21 22:12:34

标签: java android string url

我需要从url加载文本文件并将加载的数据写入String变量。我尝试了很多例子,但我没有任何想法来解决这个简单的问题。我使用min SDK 9和目标SDK版本23.在明星应用程序上的这个代码我有信息'对不起,但你的应用程序已停止'。

    public String GetVersionApk(String addres) {
    URL url;
    InputStream is = null;
    DataInputStream dis;
    int line;
    StringBuilder x = new StringBuilder();
    byte[] bytes = new byte[1000];

    try {
        url = new URL(addres);
        is = url.openStream();  // throws an IOException
        dis = new DataInputStream(new BufferedInputStream(is));

        while ((line = dis.read(bytes)) >= 0) {
            x.append(new String(bytes, 0, line));
        }
    } catch (MalformedURLException mue) {
        mue.printStackTrace();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException ioe) {
        }
    }
    return x.toString();
}

Log cat:

  

java.lang.RuntimeException:无法启动活动   ComponentInfo {} com.example.piotr.gm/com.example.piotr.gm.MapsActivity:   java.lang.NullPointerException:尝试调用虚方法'void   关于空对象引用的java.io.InputStream.close()'               在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2370)               在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432)               在android.app.ActivityThread.access $ 900(ActivityThread.java:154)               在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1321)               在android.os.Handler.dispatchMessage(Handler.java:102)               在android.os.Looper.loop(Looper.java:135)               在android.app.ActivityThread.main(ActivityThread.java:5310)               at java.lang.reflect.Method.invoke(Native Method)               在java.lang.reflect.Method.invoke(Method.java:372)               在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:904)               在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)        引发者:java.lang.NullPointerException:尝试在空对象上调用虚方法'void java.io.InputStream.close()'   参考               在com.example.piotr.gm.MapsActivity.GetVersionApk(MapsActivity.java:67)               在com.example.piotr.gm.MapsActivity.onCreate(MapsActivity.java:83)               在android.app.Activity.performCreate(Activity.java:6865)               在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)               在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2323)   在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432)   在android.app.ActivityThread.access $ 900(ActivityThread.java:154)   在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1321)   在android.os.Handler.dispatchMessage(Handler.java:102)   在android.os.Looper.loop(Looper.java:135)   在android.app.ActivityThread.main(ActivityThread.java:5310)   at java.lang.reflect.Method.invoke(Native Method)   在java.lang.reflect.Method.invoke(Method.java:372)   在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:904)   在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

编辑[22.10.2015]: 我更新了我的函数,因为我发现,该函数必须在AsyncTask中运行

private class GetVersionApk extends AsyncTask<String,String,String> {
    public AsyncResponse delegate = null;
    protected String doInBackground(String... urls) {
        URL url;
        InputStream is = null;
        DataInputStream dis;
        int line;
        StringBuilder x = new StringBuilder();
        byte[] bytes = new byte[1000];

        try {
            url = new URL(urls[0]);
            is = url.openStream();  // throws an IOException
            dis = new DataInputStream(new BufferedInputStream(is));

            while ((line = dis.read(bytes)) >= 0) {
                x.append(new String(bytes, 0, line));
            }
        } catch (MalformedURLException mue) {
            mue.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } finally {
            try{
                    is.close();
            } catch (IOException ioe) {
            }
        }
        return x.toString();
    }
}

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        Log.i("Version APK SERVER", String.valueOf(new GetVersionApk().execute("http://url.example.com/update.php")));

        //setUpMapIfNeeded();
    }

在控制台日志中我修改:

  

版本APK SERVER:com.example.piotr.gm.MapsActivity$GetVersionApk@24ed514e

在服务器文件返回文本:1akkkk

我知道,我必须在此函数中返回结果,但是如何?

protected void onPostExecute(String result) {
            delegate.processFinish(result);
        }

2 个答案:

答案 0 :(得分:0)

您应该执行以下操作,并且只有在InputStream不为空时才尝试关闭。

try {
    if(is != null) {
        is.close();
    }
} catch (IOException ioe) {
}

答案 1 :(得分:0)

尝试至少从asynctask或其他线程调用该方法。

更新:

public interface OnCallFinish {
        void processFinish(String output);
    }

private class GetVersionApk extends AsyncTask<String,String,String> {

    private OnCallFinish finished;
    public AsyncResponse delegate = null;


    public GetVersionApk(OnCallFinish finished){
        this.finished = finished;
    }


    protected String doInBackground(String... urls) {
        URL url;
        InputStream is = null;
        DataInputStream dis;
        int line;
        StringBuilder x = new StringBuilder();
        byte[] bytes = new byte[1000];

        try {
            url = new URL(urls[0]);
            is = url.openStream();  // throws an IOException
            dis = new DataInputStream(new BufferedInputStream(is));

            while ((line = dis.read(bytes)) >= 0) {
                x.append(new String(bytes, 0, line));
            }
        } catch (MalformedURLException mue) {
            mue.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } finally {
            try{
                    is.close();
            } catch (IOException ioe) {
            }
        }
        return x.toString();
    }

 @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);

            finished.processFinish(s);
        }
}

最后,在您的主线程-onCreate中 - 只需将其称为:

new GetVersionApk(new Connection.OnCallFinish() {
            @Override
            public void processFinish(String output){
                //WRITE YOUR OWN CODE        
            }}).execute();

你可能会有一些编译问题,因为我想知道,如果是这样,请告诉我。