Download Web Content - long downloading - java

I've been learning Java for a few months. Nowadays I'm creating an app which downloads web content and shows the data in a ListView. The problem is that everything takes a very long time - about 25 second from the launch of the app to fill the list with elements. What is more, there is no difference between it running on a real device or an Android emulator.
In my opinion, the Java code is not bad because most of it is from my course on Udemy.
How can I improve this? Where is the problem?
Reports from logcat and AVD setting [ss]:
Here's my code below:
MainActivity.java
package com.example.user.legionisciapp;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MainActivity extends AppCompatActivity {
ListView listView;
List<News> newsList = new ArrayList<>();
ArrayList<String> titles = new ArrayList<>();
ArrayList<String> desc = new ArrayList<>();
ArrayList<String> urls = new ArrayList<>();
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... strings) {
URL url;
HttpURLConnection connection = null;
String result = "";
try {
url = new URL(strings[0]);
connection = (HttpURLConnection) url.openConnection();
InputStream inputStream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return "Failed";
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadTask downloadTask = new DownloadTask();
try {
String result = downloadTask.execute("https://www.legionisci.com").get();
String[] resultSplit = result.split("<div id=\"mecze\">");
result = resultSplit[0];
resultSplit = result.split("<div id=\"listanewsow\">");
result = resultSplit[1];
Pattern p = Pattern.compile("class=\"b\" title=\"(.*?)\">");
Matcher m = p.matcher(result);
while (m.find()) {
titles.add(m.group(1));
}
p = Pattern.compile("></a>(.*?)</div>");
m = p.matcher(result);
while (m.find()) {
desc.add(m.group(1));
}
p = Pattern.compile("alt=\"\" class=\"zl\" /></a>(.*?)<");
m = p.matcher(result);
while (m.find()) {
urls.add("https://www.legionisci.com" + m.group(1));
}
} catch (Exception e) {
e.printStackTrace();
}
listView = findViewById(R.id.listView);
for (int i = 0; i < 4; i++) {
newsList.add(new News(R.drawable.ll, titles.get(i), desc.get(i)));
NewsListAdapter newsListAdapter = new NewsListAdapter(this, R.layout.news_list, newsList);
listView.setAdapter(newsListAdapter);
}
}
}
News.java
package com.example.user.legionisciapp;
public class News {
int image;
String title, desc;
public News(int image, String title, String desc) {
this.image = image;
this.title = title;
this.desc = desc;
}
public int getImage() {
return image;
}
public String getTitle() {
return title;
}
public String getDesc() {
return desc;
}
}
NewsListAdapter.class
package com.example.user.legionisciapp;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class NewsListAdapter extends ArrayAdapter<News> {
Context ctx;
int resource;
List<News> newsList;
public NewsListAdapter (Context ctx, int resource, List<News> newsList){
super(ctx, resource, newsList);
this.ctx = ctx;
this.resource = resource;
this.newsList = newsList;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(ctx);
View view = inflater.inflate(R.layout.news_list, null);
TextView title = view.findViewById(R.id.tvTitle);
TextView desc = view.findViewById(R.id.tvDesc);
ImageView image = view.findViewById(R.id.thumb);
News news = newsList.get(position);
title.setText(news.getTitle());
desc.setText(news.getDesc());
image.setImageDrawable(ctx.getResources().getDrawable(news.getImage()));
return view;
}
}

You can't do something like this:
String result = downloadTask.execute("https://www.legionisci.com").get();
That is not the right way to use an AsyncTask! The problem is that the async task is executed in a background thread but if you do .get() the main thread is paused until the async task finishes his job. So this is the reason of the long wait at startup.
What you have to do is:
Starting the task this way
downloadTask.execute("https://www.legionisci.com");
Using the onPostExecute(String result) method (executed on the main thread) to get the result and update the UI .
More on this:
https://developer.android.com/reference/android/os/AsyncTask

Related

JDBC connection issues in Android

I followed a tutorial on youtube, to make a list app with database.
Now I get the error:
An exception was thrown for JDBC.
This is my code:
package com.example.jopri.databaseconnectie;
import android.content.AsyncQueryHandler;
import android.content.Context;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
ItemAdapter itemAdapter;
Context thisContext;
ListView myListView;
TextView progressTextView;
Map<String, Double> fruitsMap = new LinkedHashMap<String, Double>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Resources res = getResources();
myListView = (ListView) findViewById(R.id.myListView);
progressTextView = (TextView) findViewById(R.id.progressTextView);
thisContext = this;
progressTextView.setText("");
Button btn = (Button) findViewById(R.id.getDataButton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
GetData retrieveData = new GetData();
retrieveData.execute("");
}
});
}
private class GetData extends AsyncTask<String, String, String> {
String msg = "";
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://" +
DbStrings.DATABASE_URL + "/" +
DbStrings.DATABASE_NAME;
protected void onPreExecute() {
progressTextView.setText("Connecting to database...");
}
#Override
protected String doInBackground(String... params) {
Connection conn = null;
Statement stmt = null;
try {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, DbStrings.USERNAME, DbStrings.PASSWORD);
stmt = conn.createStatement();
String sql = "SELECT * FROM fruit";
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
String soort = rs.getString("soort");
double prijs = rs.getDouble("prijs");
fruitsMap.put(soort, prijs);
}
msg = "Process complete";
rs.close();
stmt.close();
conn.close();
} catch (SQLException connError) {
msg = "An exception was thrown for JDBC";
connError.printStackTrace();
} catch (ClassNotFoundException e) {
msg = "A class not found exception was thrown.";
e.printStackTrace();
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String msg) {
progressTextView.setText(this.msg);
if(fruitsMap.size() > 0) {
itemAdapter = new ItemAdapter(thisContext, fruitsMap);
myListView.setAdapter(itemAdapter);
}
}
}
} // END
Connector:
package com.example.jopri.databaseconnectie;
import java.net.URL;
public class DbStrings {
static final String DATABASE_URL = "127.0.0.1:3306";
static final String DATABASE_NAME = "proef";
static final String USERNAME = "root";
static final String PASSWORD = "password";
}
Item adapter:
package com.example.jopri.databaseconnectie;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ItemAdapter extends BaseAdapter {
LayoutInflater mInflator;
Map<String, Double> map;
List<String> soort;
List<Double> prijs;
public ItemAdapter(Context c, Map m) {
mInflator = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
map = m;
soort = new ArrayList<String>(map.keySet());
prijs = new ArrayList<Double>(map.values());
};
#Override
public int getCount() {
return map.size();
}
#Override
public Object getItem(int position) {
return soort.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = mInflator.inflate(R.layout.item_layout, null);
TextView nameTextView = (TextView) v.findViewById(R.id.nameTextView);
TextView priceTextView = (TextView) v.findViewById(R.id.priceTextView);
nameTextView.setText(soort.get(position));
priceTextView.setText("€" + prijs.get(position).toString());
return v;
}
}
static final String DATABASE_URL = "127.0.0.1:3306";
This line implies that you're running a MySQL server on the Android device itself, which seems highly unlikely to me. If you watch over the video again, he never used localhost/127.0.0.1.
This URL should rather be a remote IP/hostname that's resolvable within your network(s) (ideally, should work over WiFi and mobile)
Also, by doing this, you're exposing your database password to anyone that can access your app/code, because it's just a plain string in memory. Therefore, in a real world environment, you'd actually use HTTP based APIs, which can more securely hide away and store database credentials in a single location, rather than have that information copied across a bunch of mobile devices (if you publish your app for others to use).
If all you want is a database with a listview, start with SQLite, which is embedded and available as a library as part of the Android SDK

Custom listView adapter, model, JSONParsing not working

I'm designing a listview that displays food information list from php server.
the url I passed is a php file after I convert it to json file. the list is not shown and whent I press refresh from menu I keep getting
(app stopped working) ..
here is FoodView.java Activity
import android.content.Context;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import alsaad.layla.mysqldemo.Models.FoodModel;
import static android.R.attr.resource;
import static android.content.Context.LAYOUT_INFLATER_SERVICE;
public class FoodView extends AppCompatActivity {
private ListView lvFood;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food_view);
lvFood = (ListView) findViewById(R.id.lvFood);
}
public class JSONTask extends AsyncTask<String, String, List<FoodModel>> {
#Override
protected List<FoodModel> doInBackground(String... params) {
HttpURLConnection httpURLConnection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
JSONArray parentArray = new JSONArray(finalJson);
List<FoodModel> foodModelList = new ArrayList<>();
for (int i = 0; i < parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);
FoodModel foodModel = new FoodModel();
foodModel.setFood(finalObject.getString("name"));
//foodModel.setStatus(finalObject.getString("status"));
foodModel.setAmount(finalObject.getInt("amount"));
foodModel.setDescription(finalObject.getString("description"));
foodModel.setDate(finalObject.getInt("exDate"));
foodModelList.add(foodModel);
}
return foodModelList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(List<FoodModel> result) {
super.onPostExecute(result);
FoodAdapter adapter = new FoodAdapter(getApplicationContext(), R.layout.row, result);
lvFood.setAdapter(adapter);
}}
public class FoodAdapter extends ArrayAdapter {
private List<FoodModel> foodModelList;
private int resource;
private LayoutInflater inflater;
public FoodAdapter(Context context, int resource, List<FoodModel> objects) {
super(context, resource, objects);
foodModelList = 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(resource, null);
}
ImageView ivIcon;
TextView foodName, txt_amount, txt_desc, txt_date, txt_status;
ivIcon = (ImageView) convertView.findViewById(R.id.ivIcon);
foodName = (TextView) convertView.findViewById(R.id.foodName);
txt_amount = (TextView) convertView.findViewById(R.id.txt_amount);
txt_desc = (TextView) convertView.findViewById(R.id.txt_desc);
// txt_status = (TextView) convertView.findViewById(R.id.txt_status);
txt_date = (TextView) convertView.findViewById(R.id.txt_date);
foodName.setText(foodModelList.get(position).getFood());
txt_amount.setText("Amount: " + foodModelList.get(position).getAmount());
txt_desc.setText(foodModelList.get(position).getDescription());
// txt_status.setText(foodModelList.get(position).getStatus());
txt_date.setText("Date: " + foodModelList.get(position).getDate());
return convertView;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.navigation_drawer, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
new JSONTask().execute("http://10.0.3.2/MySqlDemo/food.php");
return true;
}
return super.onOptionsItemSelected(item);
}
}
FoodModel.java
public class FoodModel {
private String food;
//private enum status;
private int amount;
private String image;
private String description;
private int date;
public int getDate() {
return date;
}
public void setDate(int date) {
this.date = date;
}
public String getFood() {
return food;
}
public void setFood(String food) {
this.food = food;
}
//public String getStatus() {
// return status;
// }
// public void setStatus(String status) {
// this.status = status;
//}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
the logcat error:
02-20 05:06:08.084 4514-4514/alsaad.layla.mysqldemo E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
at android.widget.ListView.setAdapter(ListView.java:462)
at alsaad.layla.mysqldemo.FoodView$JSONTask.onPostExecute(FoodView.java:128)
at alsaad.layla.mysqldemo.FoodView$JSONTask.onPostExecute(FoodView.java:54)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
It seems like you are getting an exception in your for loop that's why it goes into an exception and returns null, so it shows a null pointer exception. Please replace getString() with optSting() and getInt() with optInt().
Solution:- Please put break point in your for loop and find it out otherwise use below option.
for (int i = 0; i < parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);
FoodModel foodModel = new FoodModel();
foodModel.setFood(finalObject.optString("name"));
//foodModel.setStatus(finalObject.optString("status"));
foodModel.setAmount(finalObject.optInt("amount"));
foodModel.setDescription(finalObject.optString("description"));
foodModel.setDate(finalObject.optInt("exDate"));
foodModelList.add(foodModel);
}
return null; replace with return new ArrayList<>(); to get from crash.
The method getCount() within the ArrayAdater returns the lenght of the object list atached to the adapter:
/**
* {#inheritDoc}
*/
public int getCount() {
return mObjects.size();
}
As you are using a custom ArrayAdapter i think you must Override this function to make it returns the size of your own objects list:
public int getCount() {
return foodModelList.size();
}
Why are you using ArrayAdapter instead i would suggest you to use BaseAdapter
It is the issue when you object is not able to get instance of ArrayAdpter and hence returning null pointer exception at getCount()

How do I rewrite my method to return a list or Movie rather than a list of String?

I have would like to rewrite my method so that it returns a List of Movie class rather than a list of String class, here's the method I want to change:
private List<String> getMovieDataFromJson(String forecastJsonStr)
throws JSONException {
JSONObject movieJson = new JSONObject(forecastJsonStr);
JSONArray movieArray = movieJson.getJSONArray("results");
List<String> urls = new ArrayList<>();
for (int i = 0; i < movieArray.length(); i++) {
JSONObject movie = movieArray.getJSONObject(i);
urls.add("http://image.tmdb.org/t/p/w185" + movie.getString("poster_path"));
}
return urls;
}
I tried to rewrite it like this:
private List<Movie> getMovieDataFromJson(String forecastJsonStr)
throws JSONException {
JSONObject movieJson = new JSONObject(forecastJsonStr);
JSONArray movieArray = movieJson.getJSONArray("results");
List<Movie> movies = new ArrayList<>();
for (int i = 0; i < movieArray.length(); i++) {
JSONObject movie = movieArray.getJSONObject(i);
Movie movie1 = new Movie(movie.getString("original_title"), movie.getDouble("vote_average"), movie.getString("release_date"), movie.getString("overview"), movie.getString("poster_path"));
movies.add(movie1);
}
return movies;
}
But the problem is I'm getting error on line 139, it's saying required is String but found Movie instead. Here is line 139:
return getMovieDataFromJson(movieJsonStr);
Here is my code:
package com.projmobileapp.pmdbadd.pmdb;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivityFragment extends Fragment {
//ArrayAdapter<String> mMovieAdapter;
//String[] movieId,movieTitle,movieOverview,movieReleaseDate,movieVoteAverage;
String[] moviePosterPath = new String[0];
public MainActivityFragment() {
}
MovieAdapter mMovieAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
mMovieAdapter = new MovieAdapter(getActivity());
GridView listView = (GridView) rootView.findViewById(R.id.gridview_movie);
listView.setAdapter(mMovieAdapter);
updateMovie();
return rootView;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.mainactivityfragment, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
updateMovie();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateMovie() {
FetchMovieTask movieTask = new FetchMovieTask();
movieTask.execute();
}
class FetchMovieTask extends AsyncTask<Void, Void, List<String>> {
private final String LOG_TAG = FetchMovieTask.class.getSimpleName();
#Override
protected List<String> doInBackground(Void... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String movieJsonStr = null;
try {
URL url = new URL("http://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=INSERTAPIKEY");
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.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
movieJsonStr = buffer.toString();
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
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 {
return getMovieDataFromJson(movieJsonStr);
} catch (JSONException j) {
Log.e(LOG_TAG, "JSON Error", j);
}
return null;
}
private List<String> getMovieDataFromJson(String forecastJsonStr)
throws JSONException {
JSONObject movieJson = new JSONObject(forecastJsonStr);
JSONArray movieArray = movieJson.getJSONArray("results");
List<String> urls = new ArrayList<>();
for (int i = 0; i < movieArray.length(); i++) {
JSONObject movie = movieArray.getJSONObject(i);
urls.add("http://image.tmdb.org/t/p/w185" + movie.getString("poster_path"));
}
return urls;
}
#Override
protected void onPostExecute(List<String> strings) {
mMovieAdapter.replace(strings);
}
}
class MovieAdapter extends BaseAdapter {
private final String LOG_TAG = MovieAdapter.class.getSimpleName();
private final Context context;
private final List<String> urls = new ArrayList<String>();
public MovieAdapter(Context context) {
this.context = context;
Collections.addAll(urls, moviePosterPath);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = new ImageView(context);
}
ImageView imageView = (ImageView) convertView;
String url = getItem(position);
Log.e(LOG_TAG, " URL " + url);
Picasso.with(context).load(url).into(imageView);
return convertView;
}
#Override
public int getCount() {
return urls.size();
}
#Override
public String getItem(int position) {
return urls.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public void replace(List<String> urls) {
this.urls.clear();
this.urls.addAll(urls);
notifyDataSetChanged();
}
}
}
The problem here is that your AsyncTask defines the result type for doInBackground() as List<String>. You need to change the line:
class FetchMovieTask extends AsyncTask<Void, Void, List<String>>
to
class FetchMovieTask extends AsyncTask<Void, Void, List<Movie>>
and change doInBackground() to return List<Movie>

Android Google Place API java.lang.NullPointerException error

Im trying to add the name of the resturaunt and the category onto a card view via custom adapter. How ever when ever i run the program i keep getting a java null pointer exception. Im a little bit startled by this, i have been looking through the web but have found no luck. Thanks in advance!
//Main:
package com.example.rifatrashid.compass;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.ByteArrayBuffer;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Rifat Rashid on 2/23/2015.
*/
public class chooseactivity extends ActionBarActivity{
private ListView listView1;
ArrayList<Places> venuesList;
final String GOOGLE_KEY = "AIzaSyD72cNSZ6PoMFwvDe-ihUDNcTrAnuMynuE";
TextView t1;
final String latitude = "40.7463956";
final String longitude = "-73.9852992";
PlacesAdapter adapter1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chooselocation);
new googleplaces().execute();
/*Places place_data[] = new Places[]{
new Places("Lunch", "Mandarin Cuisine"),
new Places("Brunch", "Fredmeyer"),
new Places("Supplies", "Target")
};
*/
/*
PlacesAdapter adapter = new PlacesAdapter(this, R.layout.listview_item_row, place_data);
listView1 = (ListView) findViewById(R.id.listView);
listView1.setAdapter(adapter);
*/
}
class googleplaces extends AsyncTask<View, Void, String> { //Line54
String temp;
#Override
protected String doInBackground(View... urls) {
temp = makeCall("https://maps.googleapis.com/maps/api/place/search/json?location=" + latitude + "," + longitude + "&radius=100&sensor=true&key=" + GOOGLE_KEY);
return "";
}
#Override
protected void onPreExecute() {}
#Override
protected void onPostExecute(String result) {
if (temp == null) {
//Error coce exception
} else {
venuesList = (ArrayList<Places>) parseGoogleParse(temp);
List<String> listTitle = new ArrayList<>();
//List<Places> gPlace = new ArrayList<>();
Places[] place_data = new Places[100];
for (int i = 0; i < venuesList.size(); i++) {
//listTitle.add(i, venuesList.get(i).getName() + "\nOpen Now: " + venuesList.get(i).getOpenNow() + "\n(" + venuesList.get(i).getCategory() + ")");
new Places(venuesList.get(i).getCategory().toString(), venuesList.get(i).getName().toString()); //Line77
//gPlace.add(new Places(venuesList.get(i).getCategory(), "y"));
}
adapter1 = new PlacesAdapter(chooseactivity.this, R.layout.listview_item_row, place_data);
listView1 = (ListView) findViewById(R.id.listView);
listView1.setAdapter(adapter1);
}
}
}
public static String makeCall(String url) {
// string buffers the url
StringBuffer buffer_string = new StringBuffer(url);
String replyString = "";
// instanciate an HttpClient
HttpClient httpclient = new DefaultHttpClient();
// instanciate an HttpGet
HttpGet httpget = new HttpGet(buffer_string.toString());
try {
// get the responce of the httpclient execution of the url
HttpResponse response = httpclient.execute(httpget);
InputStream is = response.getEntity().getContent();
// buffer input stream the result
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(20);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
// the result as a string is ready for parsing
replyString = new String(baf.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(replyString);
// trim the whitespaces
return replyString.trim();
}
private static ArrayList<Places> parseGoogleParse(final String response) {
ArrayList<Places> temp = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.has("results")) {
JSONArray jsonArray = jsonObject.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++) {
Places poi = new Places();
if (jsonArray.getJSONObject(i).has("name")) {
poi.setName(jsonArray.getJSONObject(i).optString("name"));
poi.setRating(jsonArray.getJSONObject(i).optString("rating", " "));
if (jsonArray.getJSONObject(i).has("opening_hours")) {
if (jsonArray.getJSONObject(i).getJSONObject("opening_hours").has("open_now")) {
if (jsonArray.getJSONObject(i).getJSONObject("opening_hours").getString("open_now").equals("true")) {
poi.setOpenNow("YES");
} else {
poi.setOpenNow("NO");
}
}
} else {
poi.setOpenNow("Not Known");
}
if (jsonArray.getJSONObject(i).has("types")) {
JSONArray typesArray = jsonArray.getJSONObject(i).getJSONArray("types");
for (int j = 0; j < typesArray.length(); j++) {
poi.setCategory(typesArray.getString(j) + ", " + poi.getCategory());
}
}
}
temp.add(poi);
}
}
} catch (Exception e) {
e.printStackTrace();
return new ArrayList<Places>();
}
return temp;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
}
Heres my Places Class:
package com.example.rifatrashid.compass;
/**
* Created by Rifat Rashid on 2/23/2015.
*/
public class Places {
public String category;
public String name;
public String rating;
public String open;
public Places(){
super();
}
public Places(String category, String name){
super();
this.category = "";
this.name = "";
this.rating = "";
this.open = "";
}
public String getCategory(){
return category;
}
public String getOpen(){
return open;
}
public String getName(){
return name;
}
public void setName(String name) {
this.name = name;
}
public void setRating(String rating) {
this.rating = rating;
}
public void setOpenNow(String openNow) {
this.open = openNow;
}
public void setCategory(String s) {
}
public String getOpenNow() {
return open;
}
}
My custom adapter class:
package com.example.rifatrashid.compass;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
/**
* Created by Rifat Rashid on 2/23/2015.
*/
public class PlacesAdapter extends ArrayAdapter<Places> {
Context context;
int layoutResourceId;
Places[] data;
//List<Places> data;
public PlacesAdapter(Context context, int layoutResourceId, Places[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
public View getView(int position, View convertView, ViewGroup parent){
View row = convertView;
PlacesHolder holder = null;
if(row == null){
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new PlacesHolder();
holder.titleTxt = (TextView) row.findViewById(R.id.placeTitle);
holder.sub = (TextView) row.findViewById(R.id.placeCategory);
row.setTag(holder);
}else{
holder = (PlacesHolder) row.getTag();
}
Places place = data[position];
holder.titleTxt.setText(place.getName());
holder.sub.setText(place.getCategory());
return row;
}
static class PlacesHolder{
TextView titleTxt, sub;
}
}
Error:
02-26 17:05:30.530 9757-9757/com.example.rifatrashid.compass E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.rifatrashid.compass, PID: 9757
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference
at com.example.rifatrashid.compass.chooseactivity$googleplaces.onPostExecute(chooseactivity.java:77)
at com.example.rifatrashid.compass.chooseactivity$googleplaces.onPostExecute(chooseactivity.java:54)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
As your error log says, you have a problem with a line in your onPostExecute method in your googleplaces class of your chooseactivity activity. (Line 77)
Specifically, one of the elements that you're trying to call toString() on is null.
new Places(venuesList.get(i).getCategory().toString(), venuesList.get(i).getName().toString()); //Line77
To fix the error (but not necessarily your process), wrap this in an if statement that checks to see if the element is null. Like this, for example:
if (venuesList.get(i) != null && venuesList.get(i).getCategory() != null && venuesList.get(i).getName() != null) {
new Places(venuesList.get(i).getCategory().toString(), venuesList.get(i).getName().toString()); //Line77
}
Now this won't actually fix your code, just prevent this error from occurring. What you should really do is in Android Studio, put a breakpoint on Line 77 so that when you debug, you can see exactly which element is null and track back why that might be the case and how you can intercept it in the future.

displaying selected grid image in Full Screen and the code for this needs to be in the MainActivity class as shown below

public class MainActivity extends Activity {
GridView gridView;
LazyAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gridView = (GridView) findViewById(R.id.grid_view);
adapter=new LazyAdapter(this, mStrings);
gridView.setAdapter(adapter);
Button b=(Button)findViewById(R.id.button2);
b.setOnClickListener(listener);
}
#Override
public void onDestroy()
{
adapter.imageLoader.stopThread();
gridView.setAdapter(null);
super.onDestroy();
}
public OnClickListener listener=new OnClickListener(){
public void onClick(View arg0) {
adapter.imageLoader.clearCache();
adapter.notifyDataSetChanged();
}
};
private String[] mStrings={
"http://www.globaltvbc.com/uploadedImages/Global_News/Content/Wallpaper.jpeg",
"http://cdn.windows7themes.net/themes/halo-3-hd-wallpaper.jpg",
};
}
The question is i want to display the item on the gridview and display the item in full screen.I want to include any code to display the gridview item in full screen to be in the same class as MainActivity.I dont want my code to be in a new class.
if you want to load the full screen on the same activity then you should use popup window for displaying the image.
or the best solution is implement onItemClickListener on your main activity and on click get the item by position and pass the image url to next activityfor loading it there.
I am giving you my code edit this according to your need
|main Activity
package com.mypack;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.GridView;
import android.widget.RelativeLayout;
public class GridViewActivity extends Activity implements OnItemClickListener {
List<RowItem4> rowItems;
private GridView gridView;
private Button galleryButton;
private Button shareButton;
private String[] mStringArray;
public static final Integer[] partyid = { 1, 2, 3, 4, 18, 19, 20 };
int i = 1;
private String xml;
String output = "";
/*private static final String NAMESPACE = "";
private static final String URL = "";
private static final String SOAP_ACTION = "";
private static final String METHOD_NAME = "";*/
private int pos;
private ProgressDialog progressDialog;
private int galleryId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid_view);
Intent i = getIntent();
pos = i.getIntExtra("position", 0);
galleryId = i.getIntExtra("galleryId", 0);
progressDialog = ProgressDialog.show(GridViewActivity.this, "",
"Loading...");
Thread myThread = new Thread() {
private GridViewAdapter adapter;
public void run() {
getImages();
rowItems = new ArrayList<RowItem4>();
for (int i = 0; i < mStringArray.length; i++) {
RowItem4 item = new RowItem4(mStringArray[i]);
rowItems.add(item);
}
// LoadImageFromURL(""
// + output);
adapter = new GridViewAdapter(GridViewActivity.this, rowItems);
runOnUiThread(new Runnable() {
public void run() {
try {
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(GridViewActivity.this);
progressDialog.dismiss();
} catch (final Exception ex) {
Log.i("---", "Exception in thread");
}
}
});
}
};
myThread.start();
setUpView();
}
private void getImages() {
final String envelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<SOAP-ENV:Envelope SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" "
+ "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
+ "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ " xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" "
+ "xmlns:tns=\"urn:registerwsdl\">" + "<SOAP-ENV:Body>"
+ "<tns:register " + "xmlns:tns=\"urn:registerwsdl\">"
+ "<galleryid xsi:type=\"xsd:integer\">" + galleryId
+ "</galleryid>" + "<partyid xsi:type=\"xsd:integer\">"
+ partyid[pos] + "</partyid>" + "</tns:register>" +
// "</SOAP-ENV:Body></SOAP-ENV:Envelope>",Name,Email,Password,Status,Type,Date];
"</SOAP-ENV:Body></SOAP-ENV:Envelope>";
System.out.println("------------" + envelope);
CallWebService(URL, SOAP_ACTION, envelope);
org.w3c.dom.Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
ArrayList<String> myList = new ArrayList<String>();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
NodeList nl1 = doc.getElementsByTagName("response");
for (int j = 0; j < nl1.getLength(); j++) {
NodeList nl = doc.getElementsByTagName("url");
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
myList.add(node.getFirstChild().getNodeValue());
}
}
mStringArray = new String[myList.size()];
mStringArray = myList.toArray(mStringArray);
for (int i = 0; i < mStringArray.length; i++) {
Log.d("string is", (mStringArray[i]));
}
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
}
String CallWebService(String url, String soapAction, String envelope) {
final DefaultHttpClient httpClient = new DefaultHttpClient();
// request parameters
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 20000);
HttpConnectionParams.setSoTimeout(params, 25000);
// set parameter
HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true);
// POST the envelope
HttpPost httppost = new HttpPost(url);
// add headers
httppost.setHeader("soapaction", soapAction);
httppost.setHeader("Content-Type", "text/xml; charset=utf-8");
String responseString = "";
try {
// the entity holds the request
HttpEntity entity = new StringEntity(envelope);
httppost.setEntity(entity);
// Response handler
ResponseHandler<String> rh = new ResponseHandler<String>() {
// invoked when client receives response
public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
// get response entity
HttpEntity entity = response.getEntity();
// read the response as byte array
StringBuffer out = new StringBuffer();
byte[] b = EntityUtils.toByteArray(entity);
// write the response byte array to a string buffer
out.append(new String(b, 0, b.length));
return out.toString();
}
};
responseString = httpClient.execute(httppost, rh);
} catch (Exception e) {
Log.v("exception", e.toString());
}
xml = responseString.toString();
// close the connection
System.out.println("xml file ------" + xml);
httpClient.getConnectionManager().shutdown();
return responseString;
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (i == 2) {
if (galleryButton.getVisibility() == View.VISIBLE) {
galleryButton.setVisibility(View.INVISIBLE);
shareButton.setVisibility(View.INVISIBLE);
} else {
galleryButton.setVisibility(View.VISIBLE);
shareButton.setVisibility(View.VISIBLE);
}
i = 0;
}
i++;
super.dispatchTouchEvent(ev);
return false;
}
/*
* public OnTouchListener touch = new View.OnTouchListener() {
*
* public boolean onTouch(View v, MotionEvent event) {
* //System.out.println("onTouch =============-----------"); if
* (galleryButton.getVisibility() == v.VISIBLE) {
* galleryButton.setVisibility(v.INVISIBLE);
*
* shareButton.setVisibility(v.INVISIBLE);
*
* } else { galleryButton.setVisibility(v.VISIBLE);
*
* shareButton.setVisibility(v.VISIBLE);
*
* } return false; } };
*/
private void setUpView() {
gridView = (GridView) findViewById(R.id.gridView1);
galleryButton = (Button) findViewById(R.id.gallery_button);
shareButton = (Button) findViewById(R.id.share_button);
// relativeLayout1.setOnTouchListener(touch);
}
public void onItemClick(AdapterView<?> adapterView, View view,
int position, long id) {
Intent i = new Intent(getApplicationContext(), ShowImageActivity.class);
i.putExtra("image", mStringArray[position]);
i.putExtra("galleryId", galleryId);
startActivity(i);
}
}
RowItem4 Object Class
package com.mypack;
public class RowItem4 {
private String imageId;
public String getImageId() {
return imageId;
}
public void setImageId(String imageId) {
this.imageId = imageId;
}
public RowItem4(String mStringArray) {
this.imageId = mStringArray;
}
}
GridViewAdapter extending BaseAdapter
package com.mypack;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
public class GridViewAdapter extends BaseAdapter {
Context context;
List<RowItem4> rowItems;
private ViewHolder holder;
private Drawable d;
public GridViewAdapter(Context context, List<RowItem4> rowItems) {
super();
this.context = context;
this.rowItems = rowItems;
}
private class ViewHolder {
ImageView imageView;
public int position;
}
public int getCount() {
// TODO Auto-generated method stub
return rowItems.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return rowItems.get(position);
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return rowItems.indexOf(getItem(position));
}
public View getView(int position, View convertView, ViewGroup parent) {
holder = null;
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.grid_image_view, null);
holder = new ViewHolder();
holder.imageView = (ImageView) convertView.findViewById(R.id.grid_item_image);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
RowItem4 rowItem = (RowItem4) getItem(position);
holder.position = position;
GetXMLTask task = new GetXMLTask(position,holder);
task.execute(new String[] { ""+rowItem.getImageId() });
//holder.imageView.setImageDrawable(d);
return convertView;
}
/*private Drawable LoadImageFromURL(String url)
{
try
{
InputStream is = (InputStream) new URL(url).getContent();
d = Drawable.createFromStream(is, "src");
return d;
}catch (Exception e) {
System.out.println(e);
return null;
}
}*/
private class GetXMLTask extends AsyncTask<String, Void, Bitmap> {
private int mPosition;
private ViewHolder mHolder;
public GetXMLTask(int position, ViewHolder holder) {
mPosition = position;
mHolder = holder;
}
protected Bitmap doInBackground(String... urls) {
Bitmap map = null;
for (String url : urls) {
map = downloadImage(url);
}
return map;
}
// Sets the Bitmap returned by doInBackground
protected void onPostExecute(Bitmap result) {
if (mHolder.position == mPosition)
{
mHolder.imageView.setImageBitmap(result);
}
}
// Creates Bitmap from InputStream and returns it
private Bitmap downloadImage(String url) {
Bitmap bitmap = null;
InputStream stream = null;
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1;
try {
stream = getHttpConnection(url);
bitmap = BitmapFactory.
decodeStream(stream, null, bmOptions);
stream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return bitmap;
}
// Makes HttpURLConnection and returns InputStream
private InputStream getHttpConnection(String urlString)
throws IOException {
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
try {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return stream;
}
}
}
This code is if you want to load the image on second activity,and if you want to load image on the same activity just add the code for adding popup window in the main activity. I think now it is clear

Categories

Resources