Android: Custom ListView and Threading problem - android

I'm working on a small project on Android and have a serious problem with implementing some multi-threading into my solution. Below is a class that is an activity inside the tab of the main interface, which displays a custom list with pictures and data downloaded from YouTube API.
The class works fine, but it completely blocks the UI when, first the data, and then the images are being loaded from the Internet. I know I need to implement some threading and I have tried various things, but I'm not quite sure which parts of the code I have to launch as separate threads. There's also a chance there is something fundamentally wrong with my code structure.
Ideally I'd like to have the UI shown to the user immediately after the application is launched with a progress dialog on top of it, while the textual data is being loaded from YouTube. Then the user should get control of the UI, while images are being loaded in another thread in the background.
public class VodsActivity extends ListActivity {
private LayoutInflater mInflater;
private Vector<RowData> data;
RowData rd;
//private Handler mHandler;
private ProgressDialog dialog;
//Generic names of custom ListView elements
private static String[] title;
private Vector<String> detail;
private Vector<String> status;
private Vector<String> imgurl;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_list);
mInflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
title = getResources().getStringArray(R.array.yt_channels);
detail = new Vector<String>();
status = new Vector<String>();
imgurl = new Vector<String>();
//mHandler = new Handler();
//dialog = ProgressDialog.show(VodsActivity.this, "","Loading. Please wait...", true);
loadData();
displayData();
//dialog.dismiss();
}
private void loadData() {
String[] values = {"error", "error", "http://www.ephotobay.com/thumb/message-error.jpg" };
for (int i = 0; i < title.length; i++) {
values = getData(title[i]);
values[1] = getTodaysUploads(title[i]);
detail.add(i, values[0]);
status.add(i, values[1]);
imgurl.add(i, values[2]);
}
}
/*** This function gets total number of uploads and thumbnail url for the user from a single feed ***/
private String[] getData (String username) {
String[] result = new String[3];
String ytFeedUrl = "http://gdata.youtube.com/feeds/api/users/" + username + "?v=2";
InputStream inStream = null;
try {
inStream = OpenHttpConnection(ytFeedUrl);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(inStream);
Element docEle = dom.getDocumentElement();
inStream.close();
NodeList nl = docEle.getElementsByTagName("entry");
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
Element entry = (Element) nl.item(i);
Element thumbnail = (Element) entry.getElementsByTagName("media:thumbnail").item(0);
String thumbUrl = thumbnail.getAttribute("url");
Element feedLink = (Element) entry.getElementsByTagName("gd:feedLink").item(5);
String uploads = feedLink.getAttribute("countHint");
result[0] = uploads + " videos";
result[1] = ""; //not used here
result[2] = thumbUrl;
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
finally {
//
}
return result;
}
/*** This function gets a number of today's uploads of the user ***/
private String getTodaysUploads (String username) {
String result = null;
String ytFeedUrl = "http://gdata.youtube.com/feeds/api/videos?author=" + username + "&time=today&v=2";
InputStream inStream = null;
try {
inStream = OpenHttpConnection(ytFeedUrl);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(inStream);
Element docEle = dom.getDocumentElement();
inStream.close();
NodeList nl = docEle.getElementsByTagName("feed");
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
Element entry = (Element) nl.item(i);
Element title = (Element)entry.getElementsByTagName("openSearch:totalResults").item(0);
result = title.getFirstChild().getNodeValue();
result += " new today";
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
finally {
//
}
return result;
}
private void displayData () {
//Use vector instead of ArrayList for safe threading
data = new Vector<RowData>();
for (int i = 0; i < title.length; i++) { //Loop needs to be changed based on results
try {
rd = new RowData(i, title[i], detail.get(i), status.get(i));
} catch (Exception e) {
e.printStackTrace();
}
data.add(rd);
}
CustomAdapter adapter = new CustomAdapter (this, R.layout.custom_list_item, R.id.title, data);
setListAdapter(adapter);
getListView().setTextFilterEnabled(true);
}
private InputStream OpenHttpConnection(String strUrl) throws IOException {
InputStream inStream = null;
URL url = new URL(strUrl);
URLConnection conn = url.openConnection();
try {
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setRequestMethod("GET");
httpConn.connect();
if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
inStream = httpConn.getInputStream();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return inStream;
}
//This is temporary
public void onListItemClick(ListView parent, View v, int position, long id) {
CustomAdapter adapter = (CustomAdapter) parent.getAdapter();
RowData row = adapter.getItem(position);
Builder builder = new AlertDialog.Builder(this);
builder.setTitle(row.mTitle);
builder.setMessage(row.mDetail + " -> " + position );
builder.setPositiveButton("ok", null);
builder.show();
}
//Private class RowData - holds details of CustomAdapter item
private class RowData {
protected int mId;
protected String mTitle;
protected String mDetail;
protected String mStatus;
RowData (int id, String title, String detail, String status) {
mId = id;
mTitle = title;
mDetail = detail;
mStatus = status;
}
#Override
public String toString() {
return mId + " " + mTitle + " " + mDetail + " " + mStatus;
}
}
//Custom Adapter for the custom list, overrides onView() method
private class CustomAdapter extends ArrayAdapter<RowData> {
public CustomAdapter(Context context, int resource, int textViewResourceId, List<RowData> objects) {
super (context, resource, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
TextView title = null;
TextView detail = null;
TextView status = null;
ImageView image = null;
RowData rowData = getItem(position);
//Reuse existing row views
if(convertView == null) {
convertView = mInflater.inflate(R.layout.custom_list_item, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
title = holder.getTitle();
title.setText (rowData.mTitle);
detail = holder.getDetail();
detail.setText(rowData.mDetail);
status = holder.getStatus();
status.setText(rowData.mStatus);
//add if statements here for colors
image = holder.getImage();
/**** This loads the pictures ****/
BitmapFactory.Options bmOptions;
bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1;
String imageUrl = imgurl.get(rowData.mId);
Bitmap bm = LoadImage(imageUrl, bmOptions);
image.setImageBitmap(bm);
return convertView;
}
//Load image from the URL
private Bitmap LoadImage(String url, BitmapFactory.Options options) {
Bitmap bitmap = null;
InputStream inStream = null;
try {
inStream = OpenHttpConnection(url);
bitmap = BitmapFactory.decodeStream(inStream, null, options);
inStream.close();
} catch (IOException ioex) {
ioex.printStackTrace();
}
return bitmap;
}
}
/*** Wrapper for row data ***/
private class ViewHolder {
private View mRow;
private TextView title = null;
private TextView detail = null;
private TextView status = null;
private ImageView image = null;
public ViewHolder (View row) {
mRow = row;
}
public TextView getTitle() {
if (title == null) {
title = (TextView) mRow.findViewById(R.id.title);
}
return title;
}
public TextView getDetail() {
if (detail == null) {
detail = (TextView) mRow.findViewById(R.id.detail);
}
return detail;
}
public TextView getStatus() {
if (status == null) {
status = (TextView) mRow.findViewById(R.id.status);
}
return status;
}
public ImageView getImage() {
if (image == null) {
image = (ImageView) mRow.findViewById(R.id.thumbnail);
}
return image;
}
}
}
Thanks a lot for any pointers.

Check out the AsyncTask. This will let you background your long-running processes while showing the UI.
Also, you can find good/official tutorial on Android threading here.

I ended up using standard java Thread to load the data from API in the background and created a separate class for loading images in separate threads as well. In case you're wondering it now looks like this, and seem to work fine.
Loading the data:
public void onCreate(...) {
//...
mHandler = new Handler();
dialog = ProgressDialog.show(VodsActivity.this, "","Loading. Please wait...", true);
getData.start();
}
private Thread getData = new Thread() {
public void run() {
try {
loadData();
mHandler.post(showData);
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
private Runnable showData = new Runnable() {
public void run() {
try {
displayData();
dialog.dismiss();
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
Loading images (in CustomAdapter):
String imageUrl = imgurl.get(rowData.mId);
final ImageView image = holder.getImage();
//Reuse downloaded images or download new in separate thread
image.setTag(imageUrl);
Drawable cachedImage = imageLoader.loadDrawable(imageUrl, new ImageCallback() {
public void imageLoaded(Drawable imageDrawable, String imageUrl) {
ImageView imageViewByTag = (ImageView) image.findViewWithTag(imageUrl);
if (imageViewByTag != null) {
imageViewByTag.setImageDrawable(imageDrawable);
}
}
});
image.setImageDrawable(cachedImage);
ImageLoader class:
public class ImageLoader {
private HashMap<String, SoftReference<Drawable>> imageCache;
private static final String TAG = "ImageLoader";
public ImageLoader() {
imageCache = new HashMap<String, SoftReference<Drawable>>();
}
//Loads image from the cache if it exists or launches new thread to download it
public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
Log.d(TAG, "loadDrawable(" + imageUrl + ")");
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
Drawable drawable = softReference.get();
if (drawable != null) {
return drawable;
}
}
final Handler handler = new Handler() {
#Override
public void handleMessage(Message message) {
imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
}
};
new Thread() {
#Override
public void run() {
Drawable drawable = loadImageFromUrl(imageUrl);
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);
}
}.start();
return null;
}
//Downloads image from the url
public static Drawable loadImageFromUrl(String url) {
Log.d(TAG, "loadImageFromUrl(" + url + ")");
InputStream inputStream;
try {
inputStream = new URL(url).openStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
return Drawable.createFromStream(inputStream, "src");
}
public interface ImageCallback {
public void imageLoaded(Drawable imageDrawable, String imageUrl);
}
}

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'

Populate data into listview using json parsom with restful api

I have to run json format which is shown in below
and have to parse this data into listview
and for this i tried following code
MainActivity
swipeRefreshLayout.setOnRefreshListener(this);
// swipeRefreshLayout.setRefreshing(true);
swipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
SyncMethod("http://52.26.35.210/api/web/v1/api-beautician/country-state-city");
}
}
);
notification_listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
String postloadid = actorsList.get(position).gettitle();
String source_addoc=actorsList.get(position).gettitle();
Constants.vCountry=actorsList.get(position).gettitle();
Toast.makeText(getApplicationContext(),"Selecting "+ Constants.vCountry+" State ", Toast.LENGTH_LONG).show();
finish();
}
});
}
public void init()
{
norecord=(LinearLayout)findViewById(R.id.norecord);
notification_listview=(ListView)findViewById(R.id.listView_notification);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
}
#Override
public void onRefresh()
{
swipeRefreshLayout.setRefreshing(false);
SyncMethod("http://52.26.35.210/api/web/v1/api-beautician/country-state-city");
}
private static String pad(int c)
{
if (c >= 10)
return String.valueOf(c);
else
return "0" + String.valueOf(c);
}
#Override
public void onResume()
{
super.onResume();
swipeRefreshLayout.setRefreshing(false);
SyncMethod("http://52.26.35.210/api/web/v1/api-beautician/country-state-city");
}
public void SyncMethod(final String GetUrl)
{
Log.i("Url.............", GetUrl);
final Thread background = new Thread(new Runnable() {
// After call for background.start this run method call
public void run() {
try {
String url = GetUrl;
String SetServerString = "";
// document all_stuff = null;
SetServerString = fetchResult(url);
threadMsg(SetServerString);
} catch (Throwable t) {
Log.e("Animation", "Thread exception " + t);
}
}
private void threadMsg(String msg) {
if (!msg.equals(null) && !msg.equals("")) {
Message msgObj = handler11.obtainMessage();
Bundle b = new Bundle();
b.putString("message", msg);
msgObj.setData(b);
handler11.sendMessage(msgObj);
}
}
// Define the Handler that receives messages from the thread and update the progress
private final Handler handler11 = new Handler() {
public void handleMessage(Message msg) {
try {
String aResponse = msg.getData().getString("message");
Log.e("Exam", "screen>>" + aResponse);
swipeRefreshLayout.setRefreshing(false);
JSONObject jobj = new JSONObject(aResponse);
Log.e("Home Get draft--", jobj.toString());
String status = jobj.getString("status");
Log.e("Myorder Homestatusdraft",status);
Log.e("--------------------", "----------------------------------");
if (status.equalsIgnoreCase("true"))
{
actorsList = new ArrayList<Doctortype_method>();
JSONArray array = new JSONArray();
array = jobj.getJSONArray("response");
if(actorsList.size()>0){
actorsList.clear();
}
for(int i=0;i<array.length();i++)
{
JSONObject jsonChildNode = array.getJSONObject(i);
actorsList.add(new Doctortype_method(jsonChildNode.optString("State id"),jsonChildNode.optString("State name")));
}
if (getApplicationContext() != null)
{
if (adapter == null)
{
adapter = new Doctortype_Adapter(getApplicationContext(),actorsList);
notification_listview.setAdapter(adapter);
} else {
adapter.notifyDataSetChanged();
}
}
if(actorsList.size()==0)
{
norecord.setVisibility(View.VISIBLE);
}
}
else
{
swipeRefreshLayout.setRefreshing(false);
norecord.setVisibility(View.VISIBLE);
// UF.msg(message + "");
}
} catch (Exception e) {
}
}
};
});
// Start Thread
background.start();
}
public String fetchResult(String urlString) throws JSONException {
StringBuilder builder;
BufferedReader reader;
URLConnection connection = null;
URL url = null;
String line;
builder = new StringBuilder();
reader = null;
try {
url = new URL(urlString);
connection = url.openConnection();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = reader.readLine()) != null) {
builder.append(line);
}
//Log.d("DATA", builder.toString());
} catch (Exception e) {
}
//JSONArray arr=new JSONArray(builder.toString());
return builder.toString();
}
}
For this i also add adapter as well as arraylist.
but when i run this application api is not called perfectly..
hope anyone a]can help me..
here i add adapter and arraylist
Adapter
public Doctortype_Adapter(Context context, ArrayList<Doctortype_method> objects) {
super(context, R.layout.list_doctortype, objects);
this.context = context;
this.vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.actorList = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// convert view = design
//View v = convertView;
View rowView;
ViewHolder vh;
if (convertView == null) {
rowView = vi.inflate(R.layout.list_doctortype, null);
setViewHolder(rowView);
} else {
rowView = convertView;
}
vh = (ViewHolder) rowView.getTag();
vh.title.setText(Html.fromHtml(actorList.get(position).gettitle()));
vh.subtitle.setText(Html.fromHtml(actorList.get(position).getsubtitle()));
/* String image=actorList.get(position).getid();
UrlImageViewHelper.setUrlDrawable(vh.dimage, image.toString(), R.drawable.no_img);*/
return rowView;
}
static class ViewHolder {
public TextView title, subtitle;
}
private void setViewHolder(View rowView) {
ViewHolder vh = new ViewHolder();
vh.title = (TextView) rowView.findViewById(R.id.tvProfileName);
vh.subtitle = (TextView) rowView.findViewById(R.id.tvDesc);
}
}
arraylist
public Doctortype_method( String title, String subtitle) {
super();
this.title = title;
this.subtitle = subtitle;
}
public String gettitle() {
return title;
}
public void settitle(String title) {
this.title = title;
}
public String getsubtitle()
{
return subtitle;
}
public void setsubtitle(String subtitle) {
this.subtitle = subtitle;
}
there is no error but when i run this code api is not called and i didnt get the output i want.
Thnx in advance..
if (status.equalsIgnoreCase("true")) is wrong because you getting status:1 so it is if (status.equalsIgnoreCase("1")) try this and then change this array = jobj.getJSONArray("response"); to array = jobj.getJSONArray("data"); your JSONArray key is "data"
And replace this also
actorsList.add(new Doctortype_method(jsonChildNode.optString("State id"),jsonChildNode.optString("State name")));
with
actorsList.add(new Doctortype_method(jsonChildNode.optString("countryID"),jsonChildNode.optString("vCountry")));
hope this helps. if this doesn't help feel free to ask
EDIT:
I cant understand what you want but have a look at this
-> you need to create baseAdapter for listview and set that adapter into the listview with your arraylist
FOR FETCHING YOUR ABOVE DATA YOU NEED TO DO BELOW CODE:
String data;//your entire JSON data as String
try {
JSONObject object = new JSONObject(data);
String status = object.getString("status");
JSONArray dataArray = object.getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
JSONObject json1 = dataArray.getJSONObject(i);
String countryID = json1.getString("countryID");
String vCountry = json1.getString("vCountry");
}
} catch (JSONException e) {
e.printStackTrace();
}
Now if you want to show this vCountry in listview you have to add vCountry in ArrayList and then in listview.setAdapter you have to pass this ArrayList which is filled by vCountry. Hope you understand now. If you want adapter and listview code please check this link http://www.vogella.com/tutorials/AndroidListView/article.html
Finally i got the right answer.
May anyone get help from this in future.
ActivityClass.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_city_list_item);
lv_city = (ListView)findViewById(R.id.listView_city);
Bundle b=getIntent().getExtras();
city_stateid = b.getString("stateid");
city_statename=b.getString("stateName");
city_countryid=b.getString("country");
lv_city.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
page_cityname = cityist.get(position).getCityName();
SharedPreferences sp=getSharedPreferences("abc",MODE_WORLD_WRITEABLE);
SharedPreferences.Editor edit=sp.edit();
edit.putString("city_name", page_cityname);
edit.commit();
Toast.makeText(getApplicationContext(),"Selected city & State"+page_cityname + "-" +city_statename, Toast.LENGTH_LONG).show();
Intent i = new Intent(getApplicationContext(), NextActivity.class);
/*i.putExtra("cityname", page_cityname);*/
startActivity(i);
}
});
}
#Override
public void onResume() {
super.onResume();
params12 = new ArrayList<NameValuePair>();
params12.add(new BasicNameValuePair("type", city_type));
params12.add(new BasicNameValuePair("stateID", city_stateid));
params12.add(new BasicNameValuePair("countryID", city_countryid));
new Sync().execute();
}
class Sync extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(Void... params) {
String obj;//new JSONArray();
try {
// obj=getJSONFromUrl("Your posting path", params11);
obj = getJSONFromUrl("http://52.26.35.210/api/web/v1/api-beautician/country-state-city", params12);
return obj;
} catch (Exception e) {
}
return null;
}
#Override
protected void onPostExecute(final String result) {
super.onPostExecute(result);
Log.e("Result of geting data", "" + result);
try {
Log.e("Exam", "screen>>" + result);
JSONObject get_res = new JSONObject(result);
String status = get_res.getString("status");
Log.e("Exam", "screen33333>>" + status);
if (status.equalsIgnoreCase("1")) {
cityist = new ArrayList<city_method>();
JSONArray array = new JSONArray();
array = get_res.getJSONArray("data");
for (int i = 0; i < array.length(); i++) {
cityist.add(new city_method(array.getJSONObject(i).getString("cityID"),array.getJSONObject(i).getString("cityName")));
}
if (getApplicationContext() != null)
{
if (adapter == null)
{
adapter = new city_Adapter(getApplicationContext(),cityist);
lv_city.setAdapter(adapter);
} else {
adapter.notifyDataSetChanged();
}
}
}
} catch (Exception e) {
}
}
}
public String fetchResult(String urlString) throws JSONException {
StringBuilder builder;
BufferedReader reader;
URLConnection connection = null;
URL url = null;
String line;
builder = new StringBuilder();
reader = null;
try {
url = new URL(urlString);
connection = url.openConnection();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = reader.readLine()) != null) {
builder.append(line);
}
//Log.d("DATA", builder.toString());
} catch (Exception e) {
}
//JSONArray arr=new JSONArray(builder.toString());
return builder.toString();
}
public String getJSONFromUrl(String url, List<NameValuePair> params) {
InputStream is = null;
String json = "";
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
//sb.append(line + "\n");
}
is.close();
json = sb.toString();
Log.e("JSON", json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
return json;
}
}
Adapterclass.java
public class city_Adapter extends ArrayAdapter<city_method> {
ArrayList<city_method> citylist;
LayoutInflater vi;
Context context;
public city_Adapter(Context context, ArrayList<city_method> items) {
super(context, R.layout.list_doctortype, items);
this.context = context;
this.vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.citylist = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// convert view = design
//View v = convertView;
View rowView;
city_Adapter.ViewHolder vh;
if (convertView == null) {
rowView = vi.inflate(R.layout.program_list, null);
setViewHolder(rowView);
} else {
rowView = convertView;
}
vh = (city_Adapter.ViewHolder) rowView.getTag();
vh.cityid.setText((citylist.get(position).getCityID()));
vh.cityname.setText((citylist.get(position).getCityName()));
return rowView;
}
static class ViewHolder {
private TextView cityid,cityname;
}
private void setViewHolder(View rowView) {
ViewHolder vh = new ViewHolder();
vh.cityid = (TextView) rowView.findViewById(R.id.cityid);
vh.cityname = (TextView) rowView.findViewById(R.id.cityname);
rowView.setTag(vh);
}
}
Methodclass.java
public class city_method {
private String cityID,cityName;
public String getCityID() {
return cityID;
}
public void setCityID(String cityID) {
this.cityID = cityID;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public city_method(String cityID, String cityName) {
this.cityID = cityID;
this.cityName = cityName;
}
}

Imageview not showing unless rotate or resume

I am working on my movie project which fetch movie poster from URL, and then putting them into a gridview. I use asynctask to fetch JSON and the parse the url within the json file. However, when I launch my app, the grid is all empty and doing nothing until I rotate my screen or resume my app. Once I rotate my screen or resume my app. It shows all picture. I remove my api key on my code here.
public class FetchMovieTask extends AsyncTask<Void, Void, ArrayList<String>> {
private final String LOG_TAG = FetchMovieTask.class.getSimpleName();
#Override
protected ArrayList<String> doInBackground(Void... params) {
String api_key = "";
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String movieJsonStr = null;
try {
Uri.Builder builder = new Uri.Builder();
builder.scheme("http")
.authority("api.themoviedb.org")
.appendPath("3")
.appendPath("discover")
.appendPath("movie")
.appendQueryParameter("api_key", api_key);
String myUrl = builder.build().toString();
URL Url = new URL(myUrl);
Log.v(LOG_TAG, myUrl);
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) Url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
movieJsonStr = null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
movieJsonStr = null;
}
movieJsonStr = buffer.toString();
Log.v("KPN", movieJsonStr);
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attempting
// to parse it.
movieJsonStr = null;
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try {
MovieURL = getPosterUrlFromJson(movieJsonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
}
private ArrayList<String> getPosterUrlFromJson(String forcastMovieStr)
throws JSONException {
final String OWM_PosterUrl = "poster_path";
final String OWM_releaseDate = "release_date";
final String OWM_overview = "overview";
final String OWM_vote_average = "vote_average";
final String OWM_original_title = "original_title";
final String OWM_results = "results";
JSONObject movieJson = new JSONObject(forcastMovieStr);
JSONArray movieArray = movieJson.getJSONArray(OWM_results);
ArrayList<String> resultStrs = new ArrayList<>();
String posterurl = "http://image.tmdb.org/t/p/w185/";
for (int i = 0; i < movieArray.length(); i++) {
// For now, using the format "Day, description, hi/low"
String title;
String overview;
String poster;
// Get the JSON object for movie poster
JSONObject moveposter = movieArray.getJSONObject(i);
poster = moveposter.getString(OWM_PosterUrl);
resultStrs.add(i,posterurl + poster);
}
return resultStrs;
}
protected void onPostExecute(ArrayList<String> strings) {
MovieURL.clear();
for (String s : strings) {
MovieURL.add(s);
}
}
Main:
public class MainActivity extends AppCompatActivity {
public static ArrayList<String> MovieURL = new ArrayList();
public static ImageListAdapter mImageListAdapter;
public GridView gridview;
#Override
protected void onStart() {
super.onStart();
new FetchMovieTask().execute();
mImageListAdapter = new ImageListAdapter(this,MovieURL);
gridview.setAdapter(mImageListAdapter);
gridview.invalidateViews();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridview = (GridView) findViewById(R.id.gridview);
}
private void updateMovieURL(){
new FetchMovieTask().execute();
gridview.invalidateViews();
}
ImagelistAdapter class
public class ImageListAdapter extends ArrayAdapter {
private Context context;
private LayoutInflater inflater;
private ArrayList<String> imageUrls;
public ImageListAdapter(Context context, ArrayList <String> imageUrls) {
super(context, R.layout.image_view, imageUrls);
this.context = context;
this.imageUrls = imageUrls;
inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
convertView = inflater.inflate(R.layout.image_view, parent, false);
}
Picasso.with(context).load(imageUrls.get(position))
.placeholder(R.drawable.loading)
.into((ImageView) convertView);
return convertView;
}
}
THanks guys
In postExecute do this:
protected void onPostExecute(ArrayList<String> strings) {
MovieURL.clear();
for (String s : strings) {
MovieURL.add(s);
}
mImageListAdapter.notifyDataSetChanged();
}
I found my problem on the asynctask, I didnt override the onPostExecute method. After I override my onPostExecute, I initial my grid view
#Override
protected void onPostExecute(ArrayList<String> strings) {
super.onPostExecute(strings);
mImageListAdapter = new ImageListAdapter(MainActivity.this, MovieURL);
gridview.setAdapter(mImageListAdapter);
}

Parsing the same tags name for child nodes using DOM Parser Android

I'm currently building an Application which reads an xml file from the following website: http://wx.toronto.ca/festevents.nsf/tpaview?readviewentries and then displays it in a listview with an image and in a single list view. The Problem i'm facing is that once parsed using the following code :
NodeList nodeList = document.getElementsByTagName("viewentry");
it only return the first child element from the xml file. The following is a partial copy of the xml file to get an idea:
<viewentries timestamp="20141204T225826,77Z" toplevelentries="486">
<viewentry position="1" unid="76D2D8314E365A2A85257DA4004B11B7" noteid="56C06" siblings="486">
<entrydata columnnumber="0" name="EventName">
<text>Learn To Skate Lessons</text>
</entrydata>
<entrydata columnnumber="1" name="Area">
<textlist>
<text>Central East</text>
<text>Southeast</text>
</textlist>
</entrydata>
<entrydata columnnumber="2" name="CategoryList">
<textlist>
<text>Family/Children</text>
<text>Sports</text>
</textlist>
</entrydata>
<entrydata columnnumber="3" name="PresentedByOrgName">
<text/>
</entrydata>
<entrydata columnnumber="4" name="Image">
<text>
http://wx.toronto.ca/festevents.nsf/all/76D2D8314E365A2A85257DA4004B11B7/$File/learntoskate.jpg
</text>
</entrydata>
</viewentry>
The following is my Android Code...I have tested my singleListview and my imageloader than they both work.
MainActivity
public class TorontourismActivity extends Activity{
ListView listView;
ListViewAdapter adapter;
ProgressDialog progressDialog;
ArrayList<HashMap<String,String>> arrayList;
static String Event = "text";
static String Area = "text";
static String Category = "textlist";
static String Presented = "entrydata";
static String Image = "entrydata columnnumber=4 name=Image";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_main); //View from the layout file in res folder
new DownloadXMLFile().execute();
}
private class DownloadXMLFile extends AsyncTask<Void,Void,Void>
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
progressDialog = new ProgressDialog(TorontourismActivity.this);
progressDialog.setTitle("Torontourism the know it all for Toronto Events");
progressDialog.setMessage("I'm loading....Give me a minute.");
progressDialog.setIndeterminate(false);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params)
{
arrayList = new ArrayList<HashMap<String, String>>();
TorontourismParser parser = new TorontourismParser();
String xml = parser.getXMLfromURL("http://wx.toronto.ca/festevents.nsf/tpaview?readviewentries");
Document document = parser.getElements(xml);
try
{
NodeList nodeList = document.getElementsByTagName("viewentry");
for(int i =0; i < nodeList.getLength(); i++)
{
Element element = (Element) nodeList.item(i);
HashMap<String, String> map = new HashMap<String, String>();
map.put(Event, parser.getValue(element, Event));
map.put(Area, parser.getValue(element, Area));
// map.put(Category, parser.getValue(element, Category));
map.put(Image, parser.getValue(element, Image));
/*map.put(ShowDate, parser.getValue(element, ShowDate));
map.put(BeginTime, parser.getValue(element, BeginTime));
map.put(EndShowDate, parser.getValue(element, EndShowDate));*/
System.out.println(Event);
arrayList.add(map);
}
} catch (Exception e)
{
Log.i("Error in Torontourism Activity", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void arguments)
{
listView = (ListView) findViewById(R.id.listView);
adapter = new ListViewAdapter(TorontourismActivity.this, arrayList);
listView.setAdapter(adapter);
progressDialog.dismiss();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_torontourism, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
DOM Parser
public class TorontourismParser {
static final String FesEventURL = "http://wx.toronto.ca/festevents.nsf/tpaview?readviewentries";
//constructor
public TorontourismParser()
{
}
//open a HTTP Connection
public String getXMLfromURL(String urlString)
{
String xmlfile = null;
try {
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(urlString);
HttpResponse httpResponse = defaultHttpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xmlfile = EntityUtils.toString(httpEntity);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return xmlfile;
}
public Document getElements(String xml)
{
Document document = null;
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
InputSource inputSource = new InputSource();
inputSource.setCharacterStream(new StringReader(xml));
document = documentBuilder.parse(inputSource);
} catch (Exception e) {
Log.e("Error in Parser file", e.getMessage());
e.printStackTrace();
}
return document;
}
public final String getElements(Node node)
{
Node element;
StringBuilder value = new StringBuilder();
if(node != null)
{
if(node.hasChildNodes())
{
for(element = node.getFirstChild(); element != null;
element = element.getNextSibling())
{
if (element.getNodeType() == Node.TEXT_NODE)
{
value.append(element.getNodeValue());
}
}
}
}
return value.toString();
}
public String getValue(Element element, String string) {
NodeList nodeList = element.getElementsByTagName(string);
return this.getElements(nodeList.item(0));
}
}
ListViewAdapter
public class ListViewAdapter extends BaseAdapter {
Context context;
LayoutInflater layoutInflater;
ArrayList<HashMap<String,String>> xmldata;
ImageLoader imageLoader;
HashMap<String,String> hashMap = new HashMap<String, String>();
public ListViewAdapter(Context context,ArrayList<HashMap<String,String>> arrayList)
{
this.context = context;
xmldata = arrayList;
imageLoader = new ImageLoader(context);
}
#Override
public int getCount() {
return xmldata.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
public View getView(final int position, View convertView, ViewGroup parent) {
TextView Event;
TextView Area;
TextView Category;
TextView Presented;
ImageView Image;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.listview_item, parent, false);
hashMap = xmldata.get(position);
Event = (TextView) view.findViewById(R.id.Event);
Area = (TextView) view.findViewById(R.id.Area);
//Category = (TextView) view.findViewById(R.id.Category);
//Presented = (TextView) view.findViewById(R.id.Presented);
Image = (ImageView) view.findViewById(R.id.Image);
Event.setText(hashMap.get(TorontourismActivity.Event));
Area.setText(hashMap.get(TorontourismActivity.Area));
//Category.setText(hashMap.get(TorontourismActivity.Category));
// Presented.setText(hashMap.get(TorontourismActivity.Presented));
imageLoader.DisplayImage(hashMap.get(TorontourismActivity.Image),Image);
Log.i("Event:", hashMap.get(TorontourismActivity.Event));
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view1) {
hashMap = xmldata.get(position);
Intent intent = new Intent(context,SingleItemView.class);
intent.putExtra("Event", hashMap.get(TorontourismActivity.Event));
intent.putExtra("Area", hashMap.get(TorontourismActivity.Area));
// intent.putExtra("Category", hashMap.get(TorontourismActivity.Category));
//intent.putExtra("Presented", hashMap.get(TorontourismActivity.Presented));
intent.putExtra("Image", hashMap.get(TorontourismActivity.Event));
context.startActivity(intent);
}
});
return view;
}
}
Single Item viewer
public class SingleItemView extends Activity {
String Event;
String Area;
String Presented;
String Category;
String Image;
ImageLoader imageLoader = new ImageLoader(this);
#Override
public void onCreate(Bundle saveInstanceState)
{
super.onCreate(saveInstanceState);
setContentView(R.layout.singleitemview);
Intent intent = getIntent();
Event = intent.getStringExtra("Event");
Area = intent.getStringExtra("Area");
//Presented = intent.getStringExtra("Presented");
// Category = intent.getStringExtra("Category");
Image = intent.getStringExtra("Image");
TextView textView = (TextView) findViewById(R.id.Event);
//TextView textView1 = (TextView) findViewById(R.id.Area);
//TextView textView2 = (TextView) findViewById(R.id.Presented);
//TextView textView3 = (TextView) findViewById(R.id.Category);
ImageView imageView = (ImageView) findViewById(R.id.Image);
textView.setText(Event);
//textView1.setText(Area);
//textView2.setText(Presented);
//textView3.setText(Category);
imageLoader.DisplayImage(Image, imageView);
}
}
Image Loader
public class ImageLoader {
MemoryCache memoryCache = new MemoryCache();
FileCache fileCache;
private Map<ImageView, String> imageViewStringMap
= Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
Handler handler = new Handler();
public ImageLoader(Context context) {
fileCache = new FileCache(context);
executorService = Executors.newFixedThreadPool(5);
}
final int NoImage_Id = R.drawable.temp_img;
public void DisplayImage(String url, ImageView imageView) {
imageViewStringMap.put(imageView, url);
Bitmap bitmap = memoryCache.get(url);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
queuePhoto(url, imageView);
//imageView.setImageDrawable(getResources().getDrawable());
// imageView.setImageResource(R.drawable.temp_img);
}
}
private void queuePhoto(String url, ImageView imageView)
{
PhotoToLoad photoToLoad = new PhotoToLoad(url,imageView);
executorService.submit(new PhotoLoader(photoToLoad));
}
private Bitmap getBitmap(String url) {
File file = fileCache.getFile(url);
Bitmap bitmap = decodeFile(file);
if (bitmap != null)
return bitmap;
try {
Bitmap bitmap1 = null;
URL imageurl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) imageurl.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setInstanceFollowRedirects(true);
InputStream inputStream = connection.getInputStream();
OutputStream outputStream = new FileOutputStream(file);
Utils.CopyStream(inputStream, outputStream);
outputStream.close();
connection.disconnect();
bitmap = decodeFile(file);
return bitmap;
} catch (Throwable ex) {
if (ex instanceof OutOfMemoryError)
memoryCache.clear();
return null;
}
}
private Bitmap decodeFile(File file) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
FileInputStream fileInputStream = new FileInputStream(file);
BitmapFactory.decodeStream(fileInputStream, null, options);
fileInputStream.close();
final int Size = 1000;
int width_temp = options.outWidth, height_temp = options.outHeight;
int scale = 1;
while (true) {
if (width_temp / 2 < Size || height_temp / 2 < Size)
break;
width_temp /= 2;
height_temp /= 2;
scale *= 2;
}
BitmapFactory.Options options1 = new BitmapFactory.Options();
options1.inSampleSize = scale;
FileInputStream inputStream = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options1);
inputStream.close();
return bitmap;
} catch (FileNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private class PhotoToLoad
{
public String url;
public ImageView imageView;
public PhotoToLoad(String uri, ImageView ImView)
{
url = uri;
imageView = ImView;
}
}
class PhotoLoader implements Runnable
{
PhotoToLoad photoToLoad;
PhotoLoader(PhotoToLoad photoToLoad){
this.photoToLoad = photoToLoad;
}
#Override
public void run() {
try{
if(ImageViewReused(photoToLoad))
return;
Bitmap bitmap = getBitmap(photoToLoad.url);
memoryCache.put(photoToLoad.url, bitmap);
if(ImageViewReused(photoToLoad))
return;
BitmapDisplayer bitmapDisplayer = new BitmapDisplayer(bitmap,photoToLoad);
handler.post(bitmapDisplayer);
} catch (Throwable throwable){
throwable.printStackTrace();
}
}
}
boolean ImageViewReused(PhotoToLoad photoToLoad)
{
String string = imageViewStringMap.get(photoToLoad.imageView);
if(string == null || !string.equals(photoToLoad.url))
return true;
return false;
}
class BitmapDisplayer implements Runnable
{
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap bitmap1, PhotoToLoad photoToLoad1)
{
bitmap = bitmap1;
photoToLoad = photoToLoad1;
}
public void run() {
if(ImageViewReused(photoToLoad))
return;
if(bitmap != null){
photoToLoad.imageView.setImageBitmap(bitmap);
}else{
//photoToLoad.imageView.setImageResource(NoImage_Id);
}
}
}
public void clearCache()
{
memoryCache.clear();
fileCache.clear();
}
}
Any help is appreciated. From what i believe the problem lies inside the parser file. Other than that please help me.
Thank you!

Android Listview Async Image loading

I have listview at which I am trying to implement an async task that loads the image into the view inside the getView method of my adapter. I have succeeded in creating this however my problem is that since in the listview and the adapter the view gets recycled, there is a short period of time when the user scrolls the listview that the imageView located in the layout shows the image of the view at a previous position. It then shows the correct image. I have tried setting the imageView bitmap to null inside the getView method before the async task is called but it still behaves the same. How do I load an image into a view using an async task without having the previous image shown before the image is finished loading?
hey follow few step to download image from server and show in your list view
Step 1. make this class in your project
OnImageDownloaded.java
public class OnImageDownloaded {
public OnImageDownloaded() {
try {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator + "your_Dir_name");
if (file.mkdirs()) {
}
} else {
Log.e("testing", "External Directory is not mounted");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void downloadTheImages(ArrayList<String> imageUrls) {
try {
new downloadingTheImages(imageUrls).execute();
} catch (Exception e) {
e.printStackTrace();
}
}
class downloadingTheImages extends AsyncTask<Void, Void, Void> {
ArrayList<String> imageUrls;
public downloadingTheImages(ArrayList<String> imageUrls) {
this.imageUrls = imageUrls;
}
#Override
protected Void doInBackground(Void... params) {
try {
for (int i = 0; i < imageUrls.size(); i++) {
if (imageUrls.get(i).equals("0")) {
} else
downloadTheImageIfRequired(imageUrls.get(i));
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public void downloadTheImageIfRequired(String imageName) {
try {
String dirPath = Environment.getExternalStorageDirectory()
.getAbsolutePath()
+ File.separator
+ "your_Dir_name"
+ File.separator;
String CompleteFilePath = dirPath + imageName;
File f = new File(CompleteFilePath);
if (f.exists()) {
} else {
URL url = new URL(
"http image URL ::"
+ imageName);
URLConnection conexion = url.openConnection();
conexion.connect();
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(CompleteFilePath);
byte data[] = new byte[1024];
int count;
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Step 2.
Check out how you get that image
private class getImage extends AsyncTask<Void, Void, String> {
Dialog dialog;
String url;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
url = getResources().getString(R.string.baseurl) + "getNews";
JSONParser jParser = new JSONParser();
String json = jParser.getJSONFromUrl(url);
try {
JSONObject jobject = new JSONObject(json);
Log.e("testing", "url: " + url + " " + json);
int success = jobject.getInt("success");
Log.e("testing", "json length" + jobject.length());
for (int i = 0; i < jobject.length() - 1; i++) {
JSONObject jobj = jobject
.getJSONObject(Integer.toString(i));
if (success == 1) {
HashMap<String, String> hm = new HashMap<String, String>();
ArrayList<String> tempAl1 = new ArrayList<String>();
tempAl1.add(jobj.getString("image"));
if (tempAl1.size() > 0) {
new OnImageDownloaded().downloadTheImages(tempAl1);
}
Log.e("test", "image" + jobj.getString("image"));
hm.put(image, jobj.getString("image"));
aldata.add(hm);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (dialog != null)
if (dialog.isShowing())
dialog.dismiss();
Custom_Adapter adapter = new Custom_Adapter (
(Activity) context, aldata);
lv.setAdapter(adapter);
}
}
Step 3.
Show that image in your adapter like this
call these methods in your getview in adaper
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
view = null;
if (view == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.news_view, null);
final ViewHolder viewHolder = new ViewHolder();
initAll(view, viewHolder);
view.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) view.getTag();
fillAll(holder, position);
return view;
}
public void fillAll(final ViewHolder holder, final int position) {
String dirPath = Environment.getExternalStorageDirectory()
.getAbsolutePath()
+ File.separator
+ "your_Dir_name"
+ File.separator;
String CompleteFilePath = dirPath + allData.get(position).get("image");
File f = new File(CompleteFilePath);
if (f.exists()) {
Log.e("testingTag", "if part");
holder.ivimage.setVisibility(View.VISIBLE);
catchOutOfMemory(holder.ivimage, CompleteFilePath);
} else {
Log.e("testingTag", "else part");
holder.ivimage.setVisibility(View.GONE);
}
Log.e("test", "image" + allData.get(position).get("image"));
}
void catchOutOfMemory(ImageView iv, String path) {
try {
iv.setImageURI(Uri.parse(path));
} catch (OutOfMemoryError e) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap = BitmapFactory.decodeFile(path, options);
iv.setImageBitmap(preview_bitmap);
}
}
thats all thanks
I had the same problem, then I started using Square's Picasso , it's very simple and handles imageview recycling perfectly!
In your adapter, you need to use a ViewHolder (to recycle views effectively) and set a tag (on the view) to bind the view to the correct image. You already know the position in the getView(...) callback.

Categories

Resources