1

I need load text file from url and write loaded data to String variable. I tried many examples, but I haven any ide for resolve this simple problem. I use min SDK 9 and target SDK version 23. On this code on star app I have info 'Sorry, but Your app is stoped'.

    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: Unable to start activity ComponentInfo{com.example.piotr.gm/com.example.piotr.gm.MapsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.InputStream.close()' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2370) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432) at android.app.ActivityThread.access$900(ActivityThread.java:154) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5310) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.InputStream.close()' on a null object reference at com.example.piotr.gm.MapsActivity.GetVersionApk(MapsActivity.java:67) at com.example.piotr.gm.MapsActivity.onCreate(MapsActivity.java:83) at android.app.Activity.performCreate(Activity.java:6865) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2323)             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432)             at android.app.ActivityThread.access$900(ActivityThread.java:154)             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)             at android.os.Handler.dispatchMessage(Handler.java:102)             at android.os.Looper.loop(Looper.java:135)             at android.app.ActivityThread.main(ActivityThread.java:5310)             at java.lang.reflect.Method.invoke(Native Method)             at java.lang.reflect.Method.invoke(Method.java:372)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

EDIT [22.10.2015]: I updated my function, beause I found, that function must run in 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();
    }

In console log I revice:

Version APK SERVER﹕ com.example.piotr.gm.MapsActivity$GetVersionApk@24ed514e

On server file return text: 1akkkk

I know, that I must return result in this function, but how?

protected void onPostExecute(String result) {
            delegate.processFinish(result);
        }
Peter
  • 499
  • 10
  • 30

2 Answers2

0

You should do the following and only try to close the InputStream if it is not null.

try {
    if(is != null) {
        is.close();
    }
} catch (IOException ioe) {
}
jyanks
  • 2,356
  • 1
  • 19
  • 36
0

Try to call the method from an asynctask or a different thread at least.

UPDATE:

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);
        }
}

And finally, in your main thread -onCreate- just call it like:

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

YOU MIGHT HAVE SOME COMPILATION PROBLEMS SINCE I DIDN'T TRY IT, If so, let me know.

Ahmad Hammoud
  • 701
  • 1
  • 5
  • 15
  • onPostExecute(String result)... just use it because this method will invoke when the doInBackground method finishes and returns the result to the onPostExecute function. onPostExecute have access to the main thread if you want to benefit from it. – Ahmad Hammoud Oct 22 '15 at 21:43
  • I don't know what write inside `protected void onPostExecute(String result){}` for return string, and put into Log.i() in onCreate – Peter Oct 22 '15 at 21:55
  • on create, add the execution function something like : new GetVersionApk().execute(); in the onPostExecute just write Log.e("test", result); – Ahmad Hammoud Oct 22 '15 at 22:02
  • Yes, I have, but I want return string from result executed function. In log `protected void onPostExecute(String result){ Log.i("Version APK SERVER!", ""+result); }` I have string downloaded form server, but how change `Log.i...` on return string from this all asynctask function? – Peter Oct 22 '15 at 22:12
  • I will update my answer to implement it, give me a minute. – Ahmad Hammoud Oct 22 '15 at 22:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/93122/discussion-between-ahmad-hammoud-and-peter). – Ahmad Hammoud Oct 23 '15 at 00:06