I am trying to parse the following page with AsyncTask, urlConnection and InputStreamReader
public class DownloadTask extends AsyncTask<String, Void, String> {
URL url;
URLConnection urlConnection;
String result = null;
#Override
protected String doInBackground(String... urls) {
try {
url = new URL(urls[0]);
urlConnection = (URLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
And I am using this on this way:
DownloadTask downloadTask = new DownloadTask();
String data = null;
try {
data = downloadTask.execute("http://www.imdb.com/movies-in-theaters/").get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
The problem is that it takes more than 3 mins to finish the DownloadTask. Finally after this time it works on the emulator but not in a real device.
I know that this is not a good way (parsing a web page) to do stuff like that, but I am doing it for educational reasons.
Any advice how I can speed up the procedure?
Thanks!
Related
I am a beginner in the android studio. I will successfully connect the database but I don't know how to read a data 5 seconds once in an android studio.
I want to how to read data from the database every 5 seconds once
#Override
protected String doInBackground(String... voids) {
String result = "";
String name = voids[0];
String word = voids[1];
Log.d("myTag", "This is my test");
String connstr ="http://192.168.43.123/suruthi/login.php";
try {
URL url = new URL(connstr);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoInput(true);
http.setDoOutput(true);
OutputStream ops = http.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(ops, "UTF-8"));
String data = URLEncoder.encode("user", "UTF-8")+"="+URLEncoder.encode(name, "UTF-8")
+"&&"+ URLEncoder.encode("pass", "UTF-8")+"="+URLEncoder.encode(word, "UTF-8");
writer.write(data);
writer.flush();
writer.close();
ops.close();
InputStream ips = http.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(ips, "ISO-8859-1"));
String line ="";
while ((line = reader.readLine()) != null)
{
result += line;
}
reader.close();
ips.close();
http.disconnect();
return result;
} catch (MalformedURLException e) {
result = e.getMessage();
} catch (IOException e) {
result = e.getMessage();
}
return result;
}
}
The below timer function is working only image changes but it is not suitable for reading a database ever 5 sec once
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(5000);
runOnUiThread(new Runnable() {
#Override
public void run()
{
/* iv.setImageResource(mThumbIds[i]);
i++;
if(i >= mThumbIds.length)
{
i=0;
}*/
doInBackground();
}
});}}
catch (InterruptedException e)
{
}}};
}
I tried above the timer function to read a database but it is not working..please guide me to resolve the issues..
Its taking too long to compile the code (around 5mins +, only for this app).
Also when it's finally done, complete HTML is not displayed in the logcat! Only partial.
Can you guys please point out what's wrong with the code?
Is it because of "InputStream" reading character by character (as the HTML is huge)?
public class MainActivity extends AppCompatActivity {
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return "Failed";
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadTask task = new DownloadTask();
String result = null;
try {
result = task.execute("http://www.amazon.com").get();
} catch (Exception e) {
e.printStackTrace();
}
Log.i("Result",result);
}
Yes. The more system calls you make like that, the worse your performance. You should be reading in multiple kilobytes at a time, not characters. If you need to loop over it one at a time, do that afterwards.
Also, use a StringBuilder!!!! + on a string is HIGHLY inefficient. For every character you make a new String object. StringBuilder avoids that.
I am trying to download the Source code of a web page .
But the problem is the whole code is not being showing up only a small part is downloading every time .
public class MainActivity extends AppCompatActivity {
public class DownloadTask extends AsyncTask < String , Void , String >
{
#Override
protected String doInBackground(String... params) {
String content ="";
URL url ;
HttpURLConnection conn = null;
try {
url = new URL (params[0]);
conn = (HttpURLConnection)url.openConnection();
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
int data = isr.read();
while(data!=-1)
{
char c = (char) data;
content += c;
data = isr.read();
}
Log.i("The Code is ",content);
}
catch (Exception e)
{
e.getStackTrace();
}
return content;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String result =" ";
DownloadTask DT = new DownloadTask();
try {
result = DT.execute("https://www.google.co.in").get();
}
catch (Exception e)
{
e.getStackTrace();
}
Log.i("The Code is ",result);
}
}
It's important to close the StreamReader. Might not be a problem, but it's a good practice.
while(data!=-1)
{
char c = (char) data;
content += c;
data = isr.read();
}
isr.close();
is.close();
I think your first page is downloaded fine, but when you try to load it again and again you might face problem. As I said this might not be a fix, but it's important. Hope this helps someone.
I checked across StackOverflow for answers, but I did not find much. So, I am doing this for practice, like Hello World for working with JSON, I am getting JSON response from openweather API.
I write the name of the city in EditText and press the button to search for it and display JSON string in the logs.
public class MainActivity extends AppCompatActivity {
EditText city;
public void getData(View view){
String result;
String cityName = city.getText().toString();
getWeather weather = new getWeather();
try {
result = weather.execute(cityName).get();
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public class getWeather extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... urls) {
URL url;
HttpURLConnection connection = null;
String result = "";
try {
String finalString = urls[0];
finalString = finalString.replace(" ", "%20");
String fullString = "http://api.openweathermap.org/data/2.5/forecast?q=" + finalString + "&appid=a18dc34257af3b9ce5b2347bb187f0fd";
url = new URL(fullString);
connection = (HttpURLConnection) url.openConnection();
InputStream in = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while(data != -1){
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
city = (EditText) findViewById(R.id.editText);
}
}
What can I do to not get that message?
weather.execute(cityName).get()
When you do get() you are waiting the AsyncTask to finish. Thus you are running all heavy operation on Ui thread.
From documentation of get():
Waits if necessary for the computation to complete, and then retrieves its result.
Remove get().
When I'm trying to download html using this method:
public class DownloadHtml extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection connection = null;
try {
url = new URL(urls[0]);
connection = (HttpURLConnection) url.openConnection();
InputStream inputStream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
int data = reader.read();
while (data != -1) {
char currentChar = (char) data;
result += currentChar;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return "Failed";
}
}
}
And logging a result
DownloadHtml downloadHtml = new DownloadHtml();
String result = null;
try {
result = downloadHtml.execute("http://stackoverflow.com").get();
} catch (Exception e) {
e.printStackTrace();
}
Log.i("Html", result);
I am gettin only small part of it.
Is there a way to get whole HTML of webpage?
Solution was simple. Looks like Log.i doesn't print everything in one go.
When I have tried to get all the links from HTML they were successfully printed.