How do I fetch JSON data from API into ListView? - android

since I'm still kinda just starting out on more advanced android development I wanna learn more about APIs and how to fetch JSON data into a ListView.
Let's say I want to be able to search for an actor and in return get all the movies he's been involved with displaying in a listview. I've been glancing at retrofit, but not sure if it does the job I'm looking for.
I'll take any info regarding this matter. Links, snippets, you name it.

Step 1: create activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
>
<ListView
android:id="#+id/actorslist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:color="#ffffff"
android:divider="#null"
android:scrollbars="none"
/>
</RelativeLayout>
Step 2: create your RequestSenderFiles
-first create one interface AsyncResponse.java
public interface AsyncResponse
{
void processFinish(Object output) throws JSONException;
}
-Now Create Another File RequestResponse.java
public class RequestResponse extends AsyncTask<String ,String,String>
{
Activity c;
public AsyncResponse delegate = null;
String req="";
HashMap<String,String> params;
boolean connect=true;
int responseCode;
String url;
ProgressDialog Loader;
public RequestResponse(AsyncResponse AsyncResponse, Activity context, String RequestMethod)
{
delegate = AsyncResponse;
c=context;
req=RequestMethod;
}
public RequestResponse(AsyncResponse AsyncResponse, Activity context, String RequestMethod, HashMap<String, String> postparam)
{
delegate = AsyncResponse;
c=context;
req=RequestMethod;
params=postparam;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
// your progressdialog your here
Loader=new ProgressDialog(c);
Loader.setMessage("Loading...");
Loader.show();
}
#Override
protected String doInBackground(String... params)
{
String json="";
Log.i("REposnse",""+params[0]);
url=params[0];
if(req.equals("GET"))
{
json=Client(params[0]);
}
else
{
json=ClientPost(params[0]);
}
Log.i("REposnse", "" + json);
return json;
}
#Override
protected void onPostExecute(String av)
{
super.onPostExecute(av);
if(connect)
{
try
{
delegate.processFinish(av);
}
catch (JSONException e)
{
e.printStackTrace();
}
try
{
if ((this.Loader != null) && this.Loader.isShowing())
{
this.Loader.dismiss();
}
}
catch (final IllegalArgumentException e)
{
// Handle or log or ignore
}
catch (final Exception e)
{
// Handle or log or ignore
}
finally
{
this.Loader = null;
}
}
else
{
try
{
if ((this.Loader != null) && this.Loader.isShowing())
{
this.Loader.dismiss();
}
}
catch (final IllegalArgumentException e)
{
// Handle or log or ignore
}
catch (final Exception e)
{
// Handle or log or ignore
}
finally
{
this.Loader = null;
}
c.runOnUiThread(new Runnable()
{
public void run()
{
if(req.equals("GET"))
{
RequestResponse requestget= RequestResponse(delegate, c);
requestget.execute(url);
}
else
{
RequestResponse requestpost = new RequestResponse(delegate, c, req, params);
requestpost.execute(url);
}
}
});
}
}
public String ClientPost(String url)
{
URL url1;
String response = "";
try
{
url1 = new URL(url);
HttpURLConnection conn = (HttpURLConnection) url1.openConnection();
conn.setReadTimeout(1500000);
conn.setConnectTimeout(1500000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(getPostDataString(params));
writer.flush();
writer.close();
os.close();
responseCode=conn.getResponseCode();
Log.i("REposnse",""+responseCode);
if(responseCode == HttpsURLConnection.HTTP_OK)
{
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line=br.readLine()) != null)
{
response+=line;
}
}
else
{
connect=false;
response="";
}
}
catch (Exception e)
{
connect=false;
}
return response;
}
public String Client(String url)
{
String result = "";
try
{
URL apiurl =null;
HttpURLConnection conn;
String line;
BufferedReader rd;
apiurl = new URL(url);
conn = (HttpURLConnection) apiurl.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(1500000);
conn.setConnectTimeout(1500000);
responseCode=conn.getResponseCode();
Log.i("REposnse",""+responseCode);
if(responseCode==HttpsURLConnection.HTTP_OK)
{
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = rd.readLine()) != null)
{
result += line;
}
rd.close();
}
else
{
connect=false;
}
}
catch (Exception e)
{
connect=false;
}
return result;
}
private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException
{
StringBuilder result = new StringBuilder();
boolean first = true;
for(Map.Entry<String, String> entry : params.entrySet())
{
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
Log.i("REposnse",""+params);
return result.toString();
}
}
Step 3: create Activity MainActivity.java
public class MainActivity extends Activity
{
ListView list;
#Override
protected void onCreate(Bundle savedInstanceState)
{
try
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main.xml);
list = (ListView) findViewById(R.id.actorslist);
request();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void request()
{
// for POST Request
//suppose you need to send some data to server to fetch the response from server
HashMap<String,String> data=new HashMap<String,String>();
data.put("id","12");
try
{
RequestResponse crr = new RequestResponse(new AsyncResponse()
{
#Override
public void processFinish(Object output) throws JSONException
{
output.toString();//your response
// for example you got the response like this
String actors = "{"data":[{"actorname":"A"},{"actorname","B"}]}";
fetchandapplydata(actors);
}
}, this,"POST",data);
crr.execute(yourserversideurltofetchdata);
}
catch (Exception e)
{
e.printStacktrace();
}
// for GET Request
try
{
RequestResponse crr = new RequestResponse(new AsyncResponse()
{
#Override
public void processFinish(Object output) throws JSONException
{
output.toString();//your response
// for example you got the response like this
String actors = "{"data":[{"actorname":"A"},{"actorname","B"}]}";
fetchandapplydata(actors);
}
}, this,"GET");
crr.execute(yourserversideurltofetchdata);
}
catch (Exception e)
{
e.printStacktrace();
}
//Depend upon the request method use the code and comment the rest code.
}
public void fetchandapplydata(String data)
{
JSONObject object=new JSONObject(data);
JSONArray actors=object.getJSONArray("data");
ArrayList<HashMap<String,String>> actorsdata=new ArrayList<HashMap<String, String>>();
for(int i=0;i<actors.length();i++)
{
JSONObject actor=actors.getJSONObject(i);
HashMap<String,String> actorsnames=new HashMap<String,String>();
actorsnames.put("name",actor.getString("actorname"));
actorsdata.add(actorsnames);
}
ActorAdapter actoradapter = new ActorAdapter(this, actorsdata);
list.setAdapter(actoradapter);
}
}
Step 4: Create ActorAdapter.java
public class ActorAdapter extends BaseAdapter
{
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
private Activity activity;
public ActorAdapter(Activity a, ArrayList<HashMap<String, String>> d)
{
activity = a;
data=d;
inflater = (LayoutInflater)Ced_activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount()
{
return data.size();
}
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
try
{
View vi;
vi = inflater.inflate(R.layout.actor_item, null);
TextView name= (TextView) vi.findViewById(R.id.name);
HashMap<String, String> actor = new HashMap<String, String>();
actor = data.get(position);
name.setText(actor.get("name"));
return vi;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}
Step 5 : create actor_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main">
<TextView
android:layout_width="wrap_parent"
android:layout_height="wrap_parent"
android:id="#+id/name" />
</RelativeLayout>
This is step by step process for your question , still if you have any doubt feel free to ask us.

Related

Why is it not showing all the data?

I am creating this app which shows the latest news, which gets data from
https://newsapi.org/s/india-health-news-api
but it doesn't fetch all the data. Sometimes it just shows all but sometimes it just shows 2 or 3 news. Also, I don't see any log error message. What is the problem?
HealthNews.java
public class HealthNews extends AppCompatActivity {
private ArrayList urlList;
private NewsAdapter mNewsAdapter;
private static final String REQUEST_URL ="https://newsapi.org/v2/top-headlines?country=in&category=health&apiKey=3f7d99cdbb004766892bd239a4c099be";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_health_news);
Intent intent = getIntent();
HealthNews.NewsAsyncTask task = new HealthNews.NewsAsyncTask();
task.execute(REQUEST_URL);
urlList = QueryUtils.m;
ListView listView = (ListView)findViewById(R.id.listViewHealthNews);
mNewsAdapter = new NewsAdapter(this, new ArrayList<News>());
listView.setAdapter(mNewsAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Toast.makeText(getApplicationContext(), ""+ a.get(position), Toast.LENGTH_SHORT).show();
Object url = urlList.get(position);
Uri uri = (Uri) Uri.parse((String) url); // missing 'http://' will cause crashed
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
}
private class NewsAsyncTask extends AsyncTask<String, Void, ArrayList<News>> {
ProgressDialog p;
#Override
protected ArrayList<News> doInBackground(String... urls) {
if (urls.length < 1 || urls[0] == null) {
return null;
}
ArrayList<News> result = QueryUtils.fetchEarthquakeData(urls[0]);
return result;
//return null;
}
#Override
protected void onPostExecute(ArrayList<News> data) {
mNewsAdapter.clear();
if (data != null && !data.isEmpty()) {
p.hide();
mNewsAdapter.addAll(data);
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
p = new ProgressDialog(HealthNews.this);
p.setMessage("Latest News...");
p.setIndeterminate(false);
p.show();
}
}
}
QueryUtils.java
private static final String LOG_TAG = "";
private QueryUtils(){
}
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Problem building the URL ", e);
}
return url;
}
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(30000 /* milliseconds */);
urlConnection.setConnectTimeout(60000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
static ArrayList<String> m = new ArrayList<String>();
public static ArrayList<News> extractNews(String SAMPLE_JSON){
if (TextUtils.isEmpty(SAMPLE_JSON)) {
return null;
}
ArrayList<News> news = new ArrayList<News>();
try {
JSONObject jsonObject1 = new JSONObject(SAMPLE_JSON);
JSONArray baseJSONArray = jsonObject1.getJSONArray("articles");
for (int i = 0; i < baseJSONArray.length(); i++) {
JSONObject jsonObject = baseJSONArray.getJSONObject(i);
JSONObject source = jsonObject.getJSONObject("source");
String name = source.getString("name");
String article = jsonObject.getString("title");
String url1 = jsonObject.getString("url");
String img = jsonObject.getString("urlToImage");
URL url = new URL(img);
Bitmap image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
News a = new News(image, article);
news.add(a);
m.add(url1);
}
} catch (JSONException j) {
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return news;
}
public static ArrayList<News> fetchEarthquakeData(String requestUrl) {
URL url = createUrl(requestUrl);
String jsonResponse = null;
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
Log.e(LOG_TAG, "Problem making the HTTP request.", e);
}
ArrayList<News> news = extractNews(jsonResponse);
return news;
}
I went though your code and found some issues.
Some bad practices i found in your code are:
You are adding your urls in separate list with static specifier. Instead of this you should add the url variable in your News model directly. And you can directly retrieve the whole News model inside ListView > setOnItemClickListener.
You are creating Bitmap for all your images. It may cause OOM Exception. You should use any Image loading library instead.
I have fixed that all issues and created working code. Please do required changes which you want at your end.
HealthNews.java
public class HealthNews extends AppCompatActivity {
private Context context;
private NewsAdapter mNewsAdapter;
private ArrayList<News> listNews;
private static final String REQUEST_URL = "https://newsapi.org/v2/top-headlines?country=in&category=health&apiKey=3f7d99cdbb004766892bd239a4c099be";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.health_news);
context = this;
ListView list_news = findViewById(R.id.list_news);
listNews = new ArrayList<>();
mNewsAdapter = new NewsAdapter(context, listNews);
list_news.setAdapter(mNewsAdapter);
list_news.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
try {
News selNews = (News) parent.getAdapter().getItem(position);
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(selNews.getUrl())));
} catch (Exception e) {
// Missing 'http://' or 'https://' will cause crash
e.printStackTrace();
}
}
});
new NewsAsyncTask().execute(REQUEST_URL);
}
private class NewsAsyncTask extends AsyncTask<String, Void, ArrayList<News>> {
private ProgressDialog p;
#Override
public void onPreExecute() {
super.onPreExecute();
p = new ProgressDialog(context);
p.setMessage("Latest News...");
p.setIndeterminate(false);
p.show();
}
#Override
public ArrayList<News> doInBackground(String... urls) {
return QueryUtils.fetchEarthquakeData(urls[0]);
}
#Override
public void onPostExecute(ArrayList<News> newsList) {
super.onPostExecute(newsList);
listNews.addAll(newsList);
p.hide();
mNewsAdapter.notifyDataSetChanged();
}
}
}
QueryUtils.java
public class QueryUtils {
public static ArrayList<News> fetchEarthquakeData(String apiUrl) {
ArrayList<News> listNews = new ArrayList<>();
try {
URL url = new URL(apiUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(30000);
conn.setConnectTimeout(60000);
conn.setRequestMethod("GET");
conn.connect();
int responseCode = conn.getResponseCode();
InputStream iStream;
if (responseCode == HttpURLConnection.HTTP_OK)
iStream = conn.getInputStream();
else
iStream = conn.getErrorStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
String jsonResponse = response.toString();
if (TextUtils.isEmpty(jsonResponse))
return null;
JSONObject jsonObject1 = new JSONObject(jsonResponse);
JSONArray baseJSONArray = jsonObject1.getJSONArray("articles");
for (int i = 0; i < baseJSONArray.length(); i++) {
JSONObject jsonObject = baseJSONArray.getJSONObject(i);
JSONObject source = jsonObject.getJSONObject("source");
News news = new News();
news.setArticle(jsonObject.optString("title"));
news.setUrl(jsonObject.optString("url"));
news.setUrlToImage(jsonObject.optString("urlToImage"));
listNews.add(news);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return listNews;
}
}
News.java (Model)
public class News {
private String article;
private String url;
private String urlToImage;
public News() {
this.article = "";
this.url = "";
this.urlToImage = "";
}
public String getArticle() {
return article;
}
public void setArticle(String article) {
this.article = article;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
}
NewsAdapter.java (Change your item layout as per your code)
public class NewsAdapter extends BaseAdapter {
private Context context;
private LayoutInflater mInflater;
private List<News> listNews;
public NewsAdapter(Context context, List<News> listNews) {
this.context = context;
this.listNews = listNews;
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return listNews.size();
}
#Override
public News getItem(int position) {
return listNews.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
private ImageView item_img_news;
private TextView item_txt_article;
}
#SuppressLint("InflateParams")
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_news, null);
holder = new ViewHolder();
holder.item_img_news = convertView.findViewById(R.id.item_img_news);
holder.item_txt_article = convertView.findViewById(R.id.item_txt_article);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final News news = getItem(position);
holder.item_txt_article.setText(news.getArticle());
Glide.with(context).load(news.getUrlToImage()).into(holder.item_img_news);
return convertView;
}
}
app > build.gradle
implementation 'com.github.bumptech.glide:glide:4.9.0'

listview not showing items android

I am have sql DB and I am trying to display queried values in a listView. I created a custom adapter for the listView. problem is
I am not able to see any data displayed on my listView.
code of main
public class _songs_playlist extends AppCompatActivity {
ArrayList<songsarray> listofsoongs = new ArrayList<songsarray>();
private static int SPLASH_TIME_OUT=2000;
AlertDialog alertDialog;
private boolean loggedIn = false;
String type;
String result;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity__songs_playlist);
new JSONParse().execute();
MyCustomAdapterSongs itemsAdapter = new MyCustomAdapterSongs(this, listofsoongs);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(itemsAdapter);
itemsAdapter.notifyDataSetChanged();
}
private class JSONParse extends AsyncTask<String, String, JSONObject> {
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
alertDialog=new AlertDialog.Builder(_songs_playlist.this).create();
alertDialog.setTitle("Upadting Data");
pDialog = new ProgressDialog(_songs_playlist.this);
pDialog.setMessage("Getting Data ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected JSONObject doInBackground(String... args) {
HTTPHandler sh = new HTTPHandler();
String login_URL = "http://2f179dfb.ngrok.io/getsong.php";
try {
//Fetching the boolean value form sharedpreferences
URL url = new URL(login_URL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
Log.e("RESULT", result);
JSONObject jsonObject = new JSONObject(result);
JSONArray result1 = jsonObject.getJSONArray("result");
for (int i = 0; i < result1.length(); i++) {
JSONObject c = result1.getJSONObject(i);
String id = c.getString("songID");
String names = c.getString("songName");
String ss = c.getString("singerName");
listofsoongs.add(new songsarray(ss,id,names));
}
return jsonObject;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(JSONObject json) {
pDialog.dismiss();
if(true)
{
}
else
{
}
}
}
}
code of custom array adapter
public class MyCustomAdapterSongs extends ArrayAdapter<songsarray> {
Context context;
ArrayList<songsarray> items;
public MyCustomAdapterSongs(Activity context, ArrayList<songsarray> songsarrays) {
super(context, 0, songsarrays);
this.context=context;
this.items=songsarrays;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.itemlist, parent, false);
}
TextView nameTextView = (TextView) listItemView.findViewById(R.id.textView1);
nameTextView.setText(currentAndroidFlavor.getSingername());
Log.e("hhhh", nameTextView.getText().toString());
TextView numberTextView = (TextView) listItemView.findViewById(R.id.textView2);
numberTextView.setText(currentAndroidFlavor.getSongname());
Log.e("jjjj", numberTextView.getText().toString());
CheckBox ch=(CheckBox)listItemView.findViewById(R.id.checkBox1);
ch.setSelected(currentAndroidFlavor.isSelected());
return listItemView;
}
#Override
public int getCount() {
if(items == null)
return 0;
return items.size();
}
#Override
public songsarray getItem(int i) {
return items.get(i);
}
}
Call itemsAdapter.notifyDataSetChanged() within onPostExecute.
Your list is empty until the AsyncTask finishes there.
You'll have to make the adapter a member variable of the Activity class
As in your code I can see you are updating the list in doInBackground but you are not notifying the adapter for the changes.
In onPostExecute method you need to call itemsAdapter.notifyDataSetChanged() and make sure it you are not calling it inside doInBackground as in background thread you can't to UI related work.
Check the EDITS in this code snippet
`
public class _songs_playlist extends AppCompatActivity {
ArrayList<songsarray> listofsoongs = new ArrayList<songsarray>();
private static int SPLASH_TIME_OUT=2000;
AlertDialog alertDialog;
private boolean loggedIn = false;
String type;
String result;
//EDIT 1: Make these member variables
MyCustomAdapterSongs itemsAdapter;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity__songs_playlist);
//EDIT 2: get references your views before AsyncTask
listView = (ListView) findViewById(R.id.listView1);
new JSONParse().execute();
}
private class JSONParse extends AsyncTask<String, String, JSONObject> {
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
alertDialog=new AlertDialog.Builder(_songs_playlist.this).create();
alertDialog.setTitle("Upadting Data");
pDialog = new ProgressDialog(_songs_playlist.this);
pDialog.setMessage("Getting Data ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected JSONObject doInBackground(String... args) {
HTTPHandler sh = new HTTPHandler();
String login_URL = "http://2f179dfb.ngrok.io/getsong.php";
try {
//Fetching the boolean value form sharedpreferences
URL url = new URL(login_URL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
Log.e("RESULT", result);
JSONObject jsonObject = new JSONObject(result);
JSONArray result1 = jsonObject.getJSONArray("result");
for (int i = 0; i < result1.length(); i++) {
JSONObject c = result1.getJSONObject(i);
String id = c.getString("songID");
String names = c.getString("songName");
String ss = c.getString("singerName");
listofsoongs.add(new songsarray(ss,id,names));
}
return jsonObject;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(JSONObject json) {
pDialog.dismiss();
//EDIT 3: set your adapter here as this method will be called on the UI Thread
itemsAdapter = new MyCustomAdapterSongs(this, listofsoongs);
listView.setAdapter(itemsAdapter);
}
}
}
}
`

java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()

public class MainActivity extends AppCompatActivity {
ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv=(ListView)findViewById(R.id.list_id);
new JsonTask().execute("https://www.dropbox.com/s/o8yqrfm08wfdh48/Hotels.txt?dl=0");
}
class JsonTask extends AsyncTask<String,String ,List<MovieModels>>{
#Override
protected List<MovieModels> doInBackground(String...Params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(Params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream= connection.getInputStream();
reader=new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer =new StringBuffer();
String line="";
while ((line=reader.readLine())!=null){
buffer.append(line);
}
String finaljson = buffer.toString();
JSONObject parentObject = new JSONObject(finaljson);
JSONArray parentArray =parentObject.getJSONArray("Hotels");
List<MovieModels> modelsList=new ArrayList<>();
for (int i=0; i<parentArray.length();i++) {
JSONObject finalobject = parentArray.getJSONObject(i);
MovieModels models= new MovieModels();
models.setImage(finalobject.getString("Image"));
models.setHotel_Name(finalobject.getString("Hotel_Name"));
modelsList.add(models);
}
return modelsList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(List<MovieModels> result) {
super.onPostExecute(result);
Adapter adapter=new Adapter(getApplicationContext(),R.layout.row,result);
lv.setAdapter(adapter);
//to do set the data into list
}
}
public class Adapter extends ArrayAdapter{
private List<MovieModels> modelsList;
private int resource;
private LayoutInflater inflater;
public Adapter(Context context, int resource, List<MovieModels> objects) {
super(context, resource, objects);
modelsList= objects;
this.resource=resource;
inflater=(LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null){
convertView=inflater.inflate(R.layout.row,null);
}
ImageView imageView;
TextView textView;
imageView=(ImageView)convertView.findViewById(R.id.image_id);
textView=(TextView)convertView.findViewById(R.id.text_id);
ImageLoader.getInstance().displayImage(modelsList.get(position).getImage(),imageView);
textView.setText("Hotel_Name-"+modelsList.get(position).getHotel_Name());
return convertView;
}
}}
I have an error in the set adapter class, could anyone advise?
Create a class for your MovieModels like this:
public class MovieModels(){
private String imagePath, hotelName;
public MovieModels(String imagePath, String hotelName){
this.imagePath = imagePath;
this.hotelName = hotelName;
}
public String getImagePath(){
return imagePath;
}
public String getHotelName(){
return hotelName;
}
public void setImagePath(String imagePath){
this.imagePath = imagePath;
}
public void setHotelName(String hotelName){
this.hotelName = hotelName;
}
}
and then modify your doInBackground() method like this:
#Override
protected List<MovieModels> doInBackground(String...Params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
List<MovieModels> modelsList=new ArrayList<>();
try {
URL url = new URL(Params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream= connection.getInputStream();
reader=new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer =new StringBuffer();
String line="";
while ((line=reader.readLine())!=null){
buffer.append(line);
}
String finaljson = buffer.toString();
JSONObject parentObject = new JSONObject(finaljson);
JSONArray parentArray =parentObject.getJSONArray("Hotels");
for (int i=0; i<parentArray.length();i++) {
JSONObject finalobject = parentArray.getJSONObject(i);
String image = finalobject.getString("Image");
String hotelName = finalobject.getString("Hotel_Name");
modelsList.add(new MovieModels(image, hotelName));
}
return modelsList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
and your postExecute() like this:
#Override
protected void onPostExecute(List<MovieModels> result) {
super.onPostExecute(result);
if (result == null) {
Log.e("MY APPLICATION", "No result to display");
}
Adapter adapter=new Adapter(getApplicationContext(),R.layout.row,result);
lv.setAdapter(adapter);
//to do set the data into list
}
Hope it helps!!!
You return null in your doInBackground and then sets it to the adapter.
You have 2 options to solve it:
Return an empty Array e.g return new ArrayList<>(); instead of return null
or
Check don't set the adapter in case its null. e.g:
#Override
protected void onPostExecute(List<MovieModels> result) {
super.onPostExecute(result);
if (result == null) {
//todo handle no result
return;
}
Adapter adapter=new Adapter(getApplicationContext(),R.layout.row,result);
lv.setAdapter(adapter);
//to do set the data into list
}
}
Edit:
In addition, as said in the comments, your JSON Key you are trying to get ("Hotel_Name") is not like the one of the JSON itself (its "Hotel Name" in the JSON). After you fix that you will see the list, though its still important to solve the exception first.

android asynctask is not executing inside baseadapter

I have a Baseadapter for a listview, when 1 of the elements inside gets clicked it is supposed to execute an AsyncTask. The onClick is inside Baseadapter and that works however the async execute is not working here is my baseAdapter
public class LocalFeed_CustomView extends BaseAdapter {
JSONObject names;
Context ctx;
LayoutInflater myiflater;
public LocalFeed_CustomView(){}
public LocalFeed_CustomView(JSONObject arr,Context c) {
ctx = c;
names = arr;
// myiflater = (LayoutInflater)c.getSystemService(c.LAYOUT_INFLATER_SERVICE);
// System.err.println("vv:" + arr);
}
#Override
public int getCount() {
try {
JSONArray jaLocalstreams = names.getJSONArray("localstreams");
return jaLocalstreams.length();
} catch (Exception e) {
Toast.makeText(ctx,"Error: Please try again",Toast.LENGTH_LONG).show();
return names.length();
}
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position,View convertView, ViewGroup parent) {
try {
if(convertView==null) {
LayoutInflater li = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.customadapter, null);
}
TextView votes= (TextView)convertView.findViewById(R.id.votes);
JSONArray jaLocalstreams = names.getJSONArray("localstreams");
final JSONObject jsonObject = jaLocalstreams.getJSONObject(position);
jsonObject.getInt("id");
// the click works because the toast message fires
votes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
int Stream_ID= jsonObject.getInt("id");
SharedPreferences myaccount = ctx.getSharedPreferences("userInfo", ctx.MODE_PRIVATE);
int Profile_id=myaccount.getInt("id", 0);
Toast.makeText(ctx, "click worked", Toast.LENGTH_SHORT).show();
// the execute below is not firing off
new Add_Votes(Stream_ID,Profile_id).execute();
}
catch (Exception e)
{
e.getCause();
}
}
});
return convertView;
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
}
As you can see the execute is not working and both of the int values have numbers in them. This is my AsyncTask
public class Add_Votes extends AsyncTask<String,String,String> {
HttpURLConnection conn;
URL url;
String result="";
DataOutputStream wr;
String Stream_URL;
Activity m;
int stream_id,profile_id;
public Add_Votes(int stream_id,int profile_id)
{
this.stream_id=stream_id;
this.profile_id=profile_id;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Stream_URL= m.getResources().getString(R.string.PathUrl)+"/api/addvote";
//this Toast never fires off
Toast.makeText(m.getApplicationContext(),"clicked",Toast.LENGTH_SHORT);
}
#Override
protected String doInBackground(String... params) {
BufferedReader reader=null;
try{
url = new URL(Stream_URL);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
String cert="id="+profile_id+"&stream_id="+stream_id;
wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(cert);
wr.flush();
wr.close();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sBuilder = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
sBuilder.append(line + "\n");
}
result = sBuilder.toString();
reader.close();
conn.disconnect();
return result;
}
catch (Exception e)
{
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
Toast.makeText(m.getApplicationContext(),"Voted",Toast.LENGTH_SHORT).show();
}
catch (Exception e) {
Toast.makeText(m.getApplicationContext(),"Inconclusive",Toast.LENGTH_SHORT).show();
}
}
}
Add_Votes is only an AsyncTask there is no activity associated with it. Any suggestions on how I can call an AsyncTask from a baseadapter would be great. It needs to be from a baseadapter because each row has different values depending on the item clicked which then I pass on to the Async Task.
One thing I notice is you are using a variable Activity m and you have not initialised it in your AsyncTask. try passing a context from your BaseAdapter to AsyncTask.
In Add_Votes :
private Context context;
public Add_Votes(Context context ,int stream_id,int profile_id)
{
this.stream_id=stream_id;
this.profile_id=profile_id;
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(context,"clicked",Toast.LENGTH_SHORT).show();
}
In your BaseAdapter:
Add_Votes add_Votes = new Add_Votes(ctx,Stream_ID,Profile_id);
add_Votes.execute();

Android Async Task Freezes UI Completely

I have an Async task that loads information from the server and displays data on the UI. Suddenly the async task downloads the data and formats the JSON data fine but it would freeze the UI completely.
Here is the base download class
public class GetRawData {
private static String LOG_TAG = GetRawData.class.getSimpleName();
private String mRawURL;
private List<NameValuePair> mRawParams = null;
private String mRawData;
private DownloadStatus mDownloadStatus;
public GetRawData(String mRawURL) {
this.mRawURL = mRawURL;
this.mRawParams = null;
this.mDownloadStatus = DownloadStatus.IDLE;
}
public String getRawData() {
return mRawData;
}
public void setRawURL(String mRawURL) {
this.mRawURL = mRawURL;
}
public List<NameValuePair> getRawParams() {
return mRawParams;
}
public void setRawParams(List<NameValuePair> mParams) {
this.mRawParams = mParams;
}
public DownloadStatus getDownloadStatus() {
return mDownloadStatus;
}
public void reset() {
this.mRawURL = null;
this.mRawData = null;
this.mDownloadStatus = DownloadStatus.IDLE;
}
public void execute() {
this.mDownloadStatus = DownloadStatus.PROCESSING;
DownloadRawData mDownloadRawData = new DownloadRawData();
mDownloadRawData.execute(mRawURL);
}
public class DownloadRawData extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// Create URL and Reader instances.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
//If no parameter has been provided, return null.
if (params == null)
return null;
try {
// Get URL entered by the user.
URL mURL = new URL(params[0]);
urlConnection = (HttpURLConnection) mURL.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setUseCaches(false);
urlConnection.setConnectTimeout(10000);
urlConnection.setReadTimeout(10000);
urlConnection.setRequestProperty("Content-Type","application/json");
//urlConnection.setRequestProperty("Host", "android.schoolportal.gr");
urlConnection.connect();
// validate and add parameters if available.
if (mRawParams != null && mRawParams.size()>0){
JSONObject jsonParam = new JSONObject();
for (NameValuePair pair : mRawParams) {
jsonParam.put(pair.getName().toString(), pair.getValue().toString());
}
String jsonparams = jsonParam.toString();
// Send POST output.
DataOutputStream printout;
printout = new DataOutputStream(urlConnection.getOutputStream());
printout.writeBytes(jsonparams);
printout.flush();
printout.close();
}
int HttpResult =urlConnection.getResponseCode();
StringBuffer buffer = new StringBuffer();
if(HttpResult ==HttpURLConnection.HTTP_OK){
InputStream inputStream = urlConnection.getInputStream();
if (inputStream == null) {
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
System.out.println(""+buffer.toString());
}else{
InputStream errorStream = urlConnection.getErrorStream();
if (errorStream == null) {
return null;
}
reader = new BufferedReader(new InputStreamReader(errorStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
System.out.println(urlConnection.getResponseMessage());
}
return buffer.toString();
} catch (IOException e) {
Log.d("IOException", e.toString());
return null;
} catch (JSONException j) {
Log.d("JSONException", j.toString());
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
Log.d("IOException", "unable to close the reader");
}
}
}
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
mRawData = result;
//Log.d("onPostExecute", result);
if (mRawData == null) {
if (mRawURL == null) {
mDownloadStatus = DownloadStatus.NOT_INITIALIZED;
} else {
mDownloadStatus = DownloadStatus.FAILED_OR_EMPTY;
}
} else {
mDownloadStatus = DownloadStatus.PROCESSED;
}
}
private String getQuery(List<NameValuePair> params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for (NameValuePair pair : params) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
}
return result.toString();
}
}
}
enum DownloadStatus {
IDLE,
PROCESSING,
NOT_INITIALIZED,
FAILED_OR_EMPTY,
PROCESSED
}
Here is the specific data formatting class the extends above class
public class GetJobCardJsonData extends GetRawData {
private static String LOG_TAG = GetAuthenticationJsonData.class.getSimpleName();
private static String JOBCARD_SERVICE_URL = "http://www.appservice.com/appservice/jobcardinfoservice.asmx/GetJobCardInfo";
private List<JobCard> mJobCardList;
private CarcalDownloadListener mListener;
public GetJobCardJsonData(String CurrentDate, int DealershipID) {
super(null);
List<NameValuePair> mParams = new ArrayList<NameValuePair>();
mParams.add(new BasicNameValuePair("JobCardDate", CurrentDate));
mParams.add(new BasicNameValuePair("DealershipID", String.valueOf(DealershipID)));
this.setRawParams(mParams);
}
public List<JobCard> getJobCardList() {
return mJobCardList;
}
public void getjobcards() {
super.setRawURL(JOBCARD_SERVICE_URL);
DownloadJobCardJsonData mDownloadJobCardJsonData = new DownloadJobCardJsonData();
mDownloadJobCardJsonData.execute(JOBCARD_SERVICE_URL);
}
public void setOnCarcalDownloadListener(CarcalDownloadListener onCarcalDownloadListener) {
this.mListener = onCarcalDownloadListener;
}
private void processResult() {
if (getDownloadStatus() != DownloadStatus.PROCESSED) {
Log.e(LOG_TAG, "Error Downloading the raw file.");
return;
}
if (mJobCardList == null){
mJobCardList = new ArrayList<JobCard>();
}
final String JOBCARD_JOBCARDID = "JobCardID";
final String JOBCARD_GETSTOCKNUMBER_WITH_DELIVERYTIME = "StockNumberWithDeliveryTime";
final String JOBCARD_CUSTOMERNAME = "CustomerName";
final String JOBCARD_MODELNUMBER = "ModelNumber";
final String JOBCARD_COLOR = "Color";
final String JOBCARD_SALEEXECUTIVE = "SaleExecutive";
final String JOBCARD_ORDERSTATUS = "OrderStatus";
final String JOBCARD_SHOWROOMSTATUS = "ShowRoomStatus";
try {
JSONArray jsonArray = new JSONArray(getRawData());
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jobcarditem = jsonArray.optJSONObject(i);
Long JOBCARDID = jobcarditem.getLong(JOBCARD_JOBCARDID);
String STOCKWITHDELIVERY = jobcarditem.getString(JOBCARD_GETSTOCKNUMBER_WITH_DELIVERYTIME);
String CUSTOMERNAME = jobcarditem.getString(JOBCARD_CUSTOMERNAME);
String MODELNUMBER = jobcarditem.getString(JOBCARD_MODELNUMBER);
String COLOR = jobcarditem.getString(JOBCARD_COLOR);
String SALEEXECUTIVE = jobcarditem.getString(JOBCARD_SALEEXECUTIVE);
int ORDERSTATUS = jobcarditem.getInt(JOBCARD_ORDERSTATUS);
int SHOWROOMSTATUS = jobcarditem.getInt(JOBCARD_SHOWROOMSTATUS);
JobCard mJobCard = new JobCard(JOBCARDID, STOCKWITHDELIVERY, CUSTOMERNAME, MODELNUMBER, COLOR, SALEEXECUTIVE, ORDERSTATUS, SHOWROOMSTATUS);
mJobCardList.add(mJobCard);
}
} catch (JSONException jsone) {
jsone.printStackTrace();
Log.e(LOG_TAG, "Error processing json data.");
}
}
public class DownloadJobCardJsonData extends DownloadRawData {
#Override
protected String doInBackground(String... params) {
return super.doInBackground(params[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
processResult();
mListener.OnDownloadCompleted();
}
}
}
Here is the code that is called on the activity
private JobCardRecyclerViewAdapter mJobCardRecyclerViewAdapter;
private GetJobCardJsonData mGetJobCardJsonData;
SessionManager session;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_job_card_calender);
activateToolbarWithHomeEnabled();
String formattedDate="";
if (session.getCurrentDate() == ""){
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy");
formattedDate = df.format(c.getTime());
currentDateTextView.setText(formattedDate);
}else {
formattedDate = session.getCurrentDate();
currentDateTextView.setText(formattedDate);
}
// Fetch data for current date.
mGetJobCardJsonData = new GetJobCardJsonData(formattedDate, session.getDealershipID());
mGetJobCardJsonData.getjobcards();
mGetJobCardJsonData.setOnCarcalDownloadListener(new CarcalDownloadListener() {
#Override
public void OnDownloadCompleted() {
List<JobCard> mJobCards = mGetJobCardJsonData.getJobCardList();
mJobCardRecyclerViewAdapter = new JobCardRecyclerViewAdapter(mJobCards, JobCardCalenderActivity.this);
mRecyclerView.setAdapter(mJobCardRecyclerViewAdapter);
}
});
}
Can anyone help on what i am doing wrong that is freezing the UI. It was working fine before and has started to freeze the UI suddenly.
I was able to fix the issue, the problem was not with Async task but with the layout. I accidently wrapped the recycler view with scroll view. which was causing the UI to freeze. Looks weird that a scroll view caused the whole UI thread to freeze. but here is my solution
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<view
android:id="#+id/jobCardRecyclerView"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/jobCardHeader"
android:scrollbars="vertical"></view>
</ScrollView>
Changed it to
<view
android:id="#+id/jobCardRecyclerView"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/jobCardHeader"
android:scrollbars="vertical"></view>
hope it will be helpful for others facing same problem.

Categories

Resources