0

So I'm fairly new to Java and programming with android in particular. I'm trying to create an app that pulls data from a financial website (perhaps one with an API if it makes it easier).

The first step I tried was to just pull any text off a site. I'm currently practicing with a .txt URL and this is my code thus far:

package com.example.datatesting;

import java.io.IOException;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import org.apache.http.util.ByteArrayBuffer;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv = (TextView) findViewById(R.id.textView1);


        String myString = null;

        try{

            URL myURL = new URL("http://www.something.com/readme.txt");

            URLConnection connect= myURL.openConnection();

            InputStream ins = connect.getInputStream();
            BufferedInputStream buff = new BufferedInputStream(ins);


            ByteArrayBuffer baf = new ByteArrayBuffer(50);
            int current = 0;
            while( (current=buff.read()) !=-1){
                baf.append( (byte) current);
            }
            myString = new String(baf.toByteArray());
            tv.setText("hello1");
        }
        catch(Exception e){
            myString = e.getMessage();
            tv.setText("hello2");
        } 

    }
}

The code prints "hello2". I'm not quite sure whats wrong or how to fix the issue so the try block works.

I also added this into my manifest:

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

I didn't get prompted for the app to allow internet access, is it automatic?

Thanks for any help and guidance.

************Edit update: I added comments to indicate the areas of confusion

public class MainActivity extends Activity {

    private TextView tv;
    private String myString = null;

        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main); 

                tv = (TextView) findViewById(R.id.textView1);

                //I'm not sure what to put into execute(...) so I added this here, but this requires
                //a try catch block which would go back to my original issue...
                URL myURL = new URL("http://www.anddev.org/images/tut/basic/getdatafromtheweb/loadme.txt");
                new DataExtract().execute(myURL);

        }


        private class DataExtract extends AsyncTask<URL, Void, Void>{

            protected Void doInBackground(URL...urls){ //this needs a return type but I'm not returning anything 
                try{
                    URL myURL = new URL("http://www.anddev.org/images/tut/basic/getdatafromtheweb/loadme.txt");

                    URLConnection ucon = myURL.openConnection();

                    InputStream is = ucon.getInputStream();
                    BufferedInputStream bis = new BufferedInputStream(is);


                    ByteArrayBuffer baf = new ByteArrayBuffer(50);
                    int current = 0;
                    while( (current=bis.read()) !=-1){
                        baf.append( (byte) current);
                    }
                    myString = new String(baf.toByteArray());
                    tv.setText("hello1");

                }
                catch(Exception e){
                    myString = e.getMessage();
                    tv.setText("hello2");

                }
            }

            protected void onPostExecute(Void result){ //is this an acceptable param?
                tv.setText(myString);
            }


        }
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

1 Answers1

0

onCreate is executed in the application's Main (or UI) thread.

If you try to do network operations in the UI thread you will get a NetworkOnMainThreadException.

One way to fix this is to use a AsyncTask like in the answer here.

Also note that you can't touch the views from doInBackground. You can set the values to the TextView from onPostExecute.

Community
  • 1
  • 1
LordRaydenMK
  • 13,074
  • 5
  • 50
  • 56
  • My basic foundation of android revolves around using onCreate and setContentView. I'm currently trying to use the AsyncTask. I created a new private class, I'm having trouble finding a way to reference the TextView. To be clear, I should move my try catch code into the new class that extends AsyncTask ? – user3686591 May 29 '14 at 08:34
  • Your text view can be a private member of MainActivity. Your class (extending AsyncTask) can be a private class member of MainActivity. Example https://github.com/twitter-university/LearningAndroidYamba/blob/master/Yamba-1/src/com/marakana/yamba1/StatusActivity.java – LordRaydenMK May 29 '14 at 08:41
  • Thanks for all your help! I'm fairly confused on the whole AsyncTask concept, do you mind taking a look at my updated code? If so I've updated the original post to include my progress. My main struggle is with the parameters. Thanks again. – user3686591 May 29 '14 at 09:28
  • I did some corrections on your code: http://pastebin.com/kVNZqSz3 1) You can pass the String for the URI to the AsyncTask 2) You can return the String result from doInBackground and use it in onPostExecute 3) You can't use setText in doInBackgound – LordRaydenMK May 29 '14 at 09:42
  • Oh sweet!! It worked! hahaa it finally worked! Thanks so much. – user3686591 May 29 '14 at 17:17