Issue
I've been learning Java for a few months. Nowadays I'm creating an app which downloads web content and shows the data in a ListView
. The problem is that everything takes a very long time - about 25 second from the launch of the app to fill the list with elements. What is more, there is no difference between it running on a real device or an Android emulator.
In my opinion, the Java code is not bad because most of it is from my course on Udemy.
How can I improve this? Where is the problem?
Reports from logcat and AVD setting [ss]:
Here's my code below:
MainActivity.java
package com.example.user.legionisciapp;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MainActivity extends AppCompatActivity {
ListView listView;
List<News> newsList = new ArrayList<>();
ArrayList<String> titles = new ArrayList<>();
ArrayList<String> desc = new ArrayList<>();
ArrayList<String> urls = new ArrayList<>();
public class DownloadTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
URL url;
HttpURLConnection connection = null;
String result = "";
try {
url = new URL(strings[0]);
connection = (HttpURLConnection) url.openConnection();
InputStream inputStream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
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 downloadTask = new DownloadTask();
try {
String result = downloadTask.execute("https://www.legionisci.com").get();
String[] resultSplit = result.split("<div id=\"mecze\">");
result = resultSplit[0];
resultSplit = result.split("<div id=\"listanewsow\">");
result = resultSplit[1];
Pattern p = Pattern.compile("class=\"b\" title=\"(.*?)\">");
Matcher m = p.matcher(result);
while (m.find()) {
titles.add(m.group(1));
}
p = Pattern.compile("></a>(.*?)</div>");
m = p.matcher(result);
while (m.find()) {
desc.add(m.group(1));
}
p = Pattern.compile("alt=\"\" class=\"zl\" /></a>(.*?)<");
m = p.matcher(result);
while (m.find()) {
urls.add("https://www.legionisci.com" + m.group(1));
}
} catch (Exception e) {
e.printStackTrace();
}
listView = findViewById(R.id.listView);
for (int i = 0; i < 4; i++) {
newsList.add(new News(R.drawable.ll, titles.get(i), desc.get(i)));
NewsListAdapter newsListAdapter = new NewsListAdapter(this, R.layout.news_list, newsList);
listView.setAdapter(newsListAdapter);
}
}
}
News.java
package com.example.user.legionisciapp;
public class News {
int image;
String title, desc;
public News(int image, String title, String desc) {
this.image = image;
this.title = title;
this.desc = desc;
}
public int getImage() {
return image;
}
public String getTitle() {
return title;
}
public String getDesc() {
return desc;
}
}
NewsListAdapter.class
package com.example.user.legionisciapp;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class NewsListAdapter extends ArrayAdapter<News> {
Context ctx;
int resource;
List<News> newsList;
public NewsListAdapter (Context ctx, int resource, List<News> newsList){
super(ctx, resource, newsList);
this.ctx = ctx;
this.resource = resource;
this.newsList = newsList;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(ctx);
View view = inflater.inflate(R.layout.news_list, null);
TextView title = view.findViewById(R.id.tvTitle);
TextView desc = view.findViewById(R.id.tvDesc);
ImageView image = view.findViewById(R.id.thumb);
News news = newsList.get(position);
title.setText(news.getTitle());
desc.setText(news.getDesc());
image.setImageDrawable(ctx.getResources().getDrawable(news.getImage()));
return view;
}
}
Solution
You can't do something like this:
String result = downloadTask.execute("https://www.legionisci.com").get();
That is not the right way to use an AsyncTask! The problem is that the async task is executed in a background thread but if you do .get()
the main thread is paused until the async task finishes his job. So this is the reason of the long wait at startup.
What you have to do is:
Starting the task this way
downloadTask.execute("https://www.legionisci.com");
Using the onPostExecute(String result)
method (executed on the main thread) to get the result and update the UI .
More on this: https://developer.android.com/reference/android/os/AsyncTask
Answered By - Francesco Re
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.