in android how to update content of a Custom Listview - android

In my custom ListView contains two textview and one Imageview im using AsyncTask to read the Text from Internet same with the imageView .As im reading and assigning all three view elemnt at the same time it takes to much time . In such case ineed to Convert url to Bitmap in another AsyncTask when the text part is done.
As a logic it recquire some concept of updating my ImageView resource .But i do not
know how to do it....
Thanks In Advance..
private class AsynchTask extends AsyncTask<Void, Integer, Void> {
URLConnection tc;
BufferedReader in;
URL twitter;
int num=0;
#Override
protected void onPreExecute() {
super.onPreExecute();
try {
mProgressBar.setVisibility(View.VISIBLE);
} catch (Exception e) {
Log.e(TAG,""+e.getMessage());
}
}
#Override
protected Void doInBackground(Void... params) {
try{
twitter = new URL("https://twitter.com/statuses/public_timeline.json");
tc = twitter.openConnection();
my = new ArrayList<HashMap<String,Object>>();
in = new BufferedReader(new InputStreamReader(
tc.getInputStream()));
ImageList=new ArrayList<String>();
while ((line = in.readLine()) != null) {
JSONArray ja = new JSONArray(line);
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = (JSONObject) ja.get(i);
/**Data Insert into the HashMap Object*/
hm=new HashMap<String, Object>();
hm.put(TEXT,jo.getString("text"));
hm.put(USER,jo.getJSONObject("user").getString("name"));
// String str=jo.getJSONObject("user").getString("profile_image_url"); hm.put(URL,"http://twitter.com/#!/"+jo.getJSONObject("user").getString("screen_name"));
// hm.put(IMAGEURL,getDrawable_from_url(str));
ImageList.add(jo.getJSONObject("user").getString("profile_image_url"));
Log.e(TAG,""+num);
my.add(hm);
num++;
Log.e("Count",""+num);
publishProgress(num);
}
num++;
publishProgress(num);
}
} catch (Exception e) {
Log.e(TAG,""+e.getMessage());
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
mProgressBar.setProgress(values[0]);
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mProgressBar.setProgress(0);
mProgressBar.setVisibility(View.GONE);
adapter = new Simpleadapter(HelloWorldActivity.this, my, R.layout.listcontent,
new String[]{TEXT,USER}, new int[]{R.id.text2,R.id.text1});
listView.setAdapter(adapter);
new AsynchTaskForImageLoading().execute();
}
}
/**Method to convert Url to the Bitmap*/
private Bitmap getDrawable_from_url(String url) {
try{
Bitmap x;
HttpURLConnection connection = (HttpURLConnection)new URL(url).openConnection();
connection.setRequestProperty("User-agent","Mozilla/4.0");
connection.connect();
InputStream input = connection.getInputStream();
x = BitmapFactory.decodeStream(input);
return x;
}
catch (Exception e) {
Log.e(TAG,""+e.getMessage());
return null;
}
}

I've used this LazyList with great success: https://github.com/thest1/LazyList
For your needs, you can swap out the supplied stub image with the one you'd like to use. I've also used a 1x1 blank png to show no image.
Also, one change that i've made in my code and that I strongly suggest when using this package is to change the code from using the SD card to use the built in cache. You do this by modifying the FileCache.java file from using .getExternalStorageDirectory() to .getCacheDir().
Hope this helps.

Related

arraymap is better than sparse array to memorise some data catched from a JSON file?

I had wrote a code which use a parse to catch some data from a JSON file but i don't know what kind of structure is better between the sparse array or the array map for memorise these data ?
I had used a array map but I don't know if it's too wasted on so little data data.
public class MainActivity extends AppCompatActivity {
private ProgressDialog pd;
private String TAG = MainActivity.class.getSimpleName();
public ArrayMap<Integer, ValoriDiSueg> ArrayDati = new ArrayMap<>();
Button buttonProg;
TextView textViewProg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonProg = (Button) findViewById(R.id.button);
textViewProg = (TextView) findViewById(R.id.textView);
buttonProg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new JsonCLASS().execute("https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22");
}
});
}
private class JsonCLASS extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(MainActivity.this);
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
#Override
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
Log.d("Response: ", "> " + line); //here u ll get whole response...... :-)
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
The parse of these data
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray Arr = new JSONArray(jsonObject.getString("weather"));
for (int i = 0; i < Arr.length(); i++){
JSONObject jsonPart = Arr.getJSONObject(i);
ArrayDati.put(i,new ValoriDiSueg( jsonPart.getString("main"), jsonPart.getString("description")));
//ArrayDati.put(i,new ValoriDiSueg("description : "+ jsonPart.getString("description")));
textViewProg.setText(textViewProg.getText()+"main : "+ ArrayDati.get(i).Main +"\n"+textViewProg.getText()+"description : "+ ArrayDati.get(i).Description );
}
} catch (Exception e ){
e.printStackTrace();
}
if (pd.isShowing()) {
pd.dismiss();
}
}
}
}
And I created a class:
public class ValoriDiSueg {
String Main;
String Description;
public ValoriDiSueg(String main, String description) {
this.Main = main;
this.Description = description;
}
}
any suggestions??
In simple:
If your key is int or long, you should use SparseArray, SparseLongArray as it will not boxing/un-boxing the key value when operates. Also, it provides similar classes for int/long values as long as the key is int/long.
If you key is not int nor long, such as an object or String, you should use ArrayMap instead as it will handle the conflicts of key hashes.
There are no much performance and memory usage difference between these two class as they are all requires O(log n) to search and O(n) to insert/delete (in most cases).

i want to download the html content of a website using asynctask and display result in a listview

i want to download the html content of a website using asynctask, and use regex to manipulate the source code to get what i need and finally i want to display those result in a list view. this is my code it doesnt show error but when i run it on my emulator the app crashes
please guys i need assistant this is really important
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection)url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView myLV = (ListView)findViewById(R.id.teamLV);
ArrayList<String> clubName = new ArrayList<String>();
DownloadTask task = new DownloadTask();
String result = null;
try {
result = task.execute("https://www.premierleague.com/clubs").get();
//Log.i("Content of URL", result);
System.out.println(result);
Pattern p = Pattern.compile("class=\"clubName\">(.*?)<");
Matcher m = p.matcher(result);
while(m.find()){
System.out.println(m.group(1));
clubName.add(m.group(1));
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_activated_1, clubName);
myLV.setAdapter(arrayAdapter);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
try adding onPostExecute after doInBackground. then remove the part from execute.get(). The get method makes the UI blocking (which kinda makes the asynctask pointless).
also preset your adapter instead of creating a new one each time you do a loop. you might need a custom adapter (depending on what you need).
#Override
protected void onPostExecute(String result) {
//Log.i("Content of URL", result);
System.out.println(result);
Pattern p = Pattern.compile("class=\"clubName\">(.*?)<");
Matcher m = p.matcher(result);
while(m.find()){
System.out.println(m.group(1));
// clubName.add(m.group(1));
adapter.add (m.group(1));
}
}

How to parse data from two json by using AssyncTask method?

I have seen one similar question to this, but i couldn't solve my problem like he did.
Here i'm getting data from url:
public class AsyncHttpTask extends AsyncTask<String, Void, Integer> {
#Override
protected void onPreExecute() {
setProgressBarIndeterminateVisibility(true);
}
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP Ok
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
parseResult(response.toString());
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
// Download complete. Let us update UI
progressBar.setVisibility(View.GONE);
if (result == 1) {
giftListAdapter = new GiftListAdapter(GiftsActivity.this, gifts);
recyclerView.setAdapter(giftListAdapter);
} else {
SuperActivityToast.create(GiftsActivity.this, getString(R.string.no_internet_connection),
SuperToast.Duration.SHORT, Style.getStyle(Style.RED, SuperToast.Animations.FLYIN)).show();
}
}
}
private void parseResult(String result) {
try {
JSONObject response = new JSONObject(result);
JSONArray posts = response.optJSONArray("gifts");
gifts = new ArrayList<>();
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.optJSONObject(i);
GiftItem item = new GiftItem();
item.setThumbnail(post.optString("image"));
item.setTitle(post.optString("title"));
item.setDescription(post.optString("description"));
item.setSource(getString(R.string.source) + " " + post.optString("source"));
item.setTotalRating(post.optInt("rating"));
item.setPrice(post.optDouble("price"));
gifts.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
And here i'm executing that url. I'm trying now to parse this second url and load all items after first data is loaded:
new AsyncHttpTask().execute(url_movies);
new AsyncHttpTask().execute(url_books); // This is the second url i'm trying to get
How could i do that?
I'm trying now to parse this second url and load all items after first
data is loaded:
Then instead of calling execute method just after first, call it inside onPostExecute method when first url all items are loaded successfully.
Also add second call in if-else block to avoid it execute again :
#Override
protected void onPostExecute(Integer result) {
// Download complete. Let us update UI
progressBar.setVisibility(View.GONE);
... your code here
if(params[0].equals(url_movies)){
new AsyncHttpTask().execute(url_books);
}
}
also add
If you want both urls than send them as an String array like this
String urls[] = new String[]{"url1" , "url2"};
new AsyncHttpTask().execute(urls);
and in doinbackground method exec them like
url1 = params[0];
url2 = params[1];

Adding bitmap received from server to an image gridview in android

I have an android code which receives images as base64 string from the server in the form of json data. The code is given below. After receiving the images I have to decode the images as bitmap. And after that I have to display that images in an image gridview. How can this acheived? please help me. Thanks in advance.
package com.example.mygallery;
//skipping the import section
public class Gallery extends Activity
{
int refresh=0;
Bitmap decodedByte;
GridView gridView;
String username,password,count1,status;
int count;
ArrayList<String>imagearraylist;
ProgressDialog pd;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
gridView = (GridView) findViewById(R.id.grid_view);
SharedPreferences sp=getSharedPreferences("My_login", MODE_PRIVATE);
username=sp.getString("username", "");
password=sp.getString("password", "");
new serverconnection().execute();
}
public class serverconnection extends AsyncTask<Void, String, Void>
{
#Override
protected Void doInBackground(Void... params)
{
// TODO Auto-generated method stub
try
{
String link="http://tonyjoseph.site90.com/sendimage.php";
String data = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(username, "UTF-8");
URL url = new URL(link);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter (conn.getOutputStream());
wr.write( data );
wr.flush();
BufferedReader reader = new BufferedReader (new InputStreamReader(conn.getInputStream()));
StringBuilder sb=new StringBuilder();
String line = null; // Read Server Response
while((line = reader.readLine()) != null)
{
sb.append(line);
break;
}
String status=sb.toString();
JSONObject jsonResponse1;
try
{
/****** Creates a new JSONObject with name/value mappings from the JSON string. ********/
jsonResponse1 = new JSONObject(status);
/***** Returns the value mapped by name if it exists and is a JSONArray. Returns null otherwise.*******/
JSONArray jsonMainNode=jsonResponse1.optJSONArray("Android");
/*********** Process each JSON Node ************/
int lengthJsonArr = jsonMainNode.length();
Log.d("Json Array Length",String.valueOf(lengthJsonArr));
for(int j1=0;j1<lengthJsonArr;j1++)
{
Context mContext;
/****** Get Object for each JSON node.***********/
JSONObject jsonChildNode = jsonMainNode.getJSONObject(j1);
/******* Fetch node values **********/
String index=jsonChildNode.optString("index").toString();
String imagename=jsonChildNode.optString("imagename").toString();
//Here I get the images from server as string one after another
byte[] decodedString = Base64.decode(imagename, Base64.DEFAULT);
decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
// At this stage I will be getting a list of bitmapsfrom the server which is converted from the received json
// i need to display these bitmaps into a image grid view ie display the images as a grid
// how can this be acheived??
}
}
catch(Exception ex)
{
System.out.print(ex);
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
// TODO Auto-generated method stub
super.onPostExecute(result);
Toast.makeText(Gallery.this, "Loading complete", Toast.LENGTH_LONG).show();
pd.dismiss();
}
#Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
super.onPreExecute();
pd=new ProgressDialog(Gallery.this);
pd.setTitle("Loading images..");
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
}
}
At that stage use runOnUiThread to place the received Bitmap 'in the grid'. But if you do not first save or cache all received bitmaps the grid will loose them with UI updates. The actual placing in the grid will be done by getView() calls after notify dataset changed.
Actually you do not need runOnUiThread at all. Just in doInBackGround save all images to a specific folder. Then in onPostExecute do a notifyDataSetChanged. The listview knows to retrieve from that folder.

Android Downloading several Pages

I have a problem. When I click a button I have to download a main page from a website (the source). Then I have to parse the source to get other links from it. After that I have to add as many rows to my list view as I have found links in the main page source. And finally I have to download each link (the source again) and parse them. During the downloading / parsing I have to update my list view (the progressbar for example) with the information I get from these sources.
But how do I do that?
I thought I could just create two classes which both extends the AsyncTask. A MainPageDownloader and a PageDownloader. The MainPageDownloader would be started on button click. It downloads the main page and in the onPostExecute method it will parse the source and add the rows to the list. And then it will start the PageDownloaders.
I tried that but the PageDownloaders will start when the list has not even been updated yet. So I cannot update the ProgressBar's in each row.
What am I doing wrong? Is there maybe a whole different and better way?
Here are the two classes :
public class MainPageDownloader extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... params) {
InputStream in = null;
final int BUFSIZE = 1024;
String result = "";
try {
URL url = new URL( params[0] );
URLConnection con = url.openConnection();
con.connect();
in = con.getInputStream();
byte[] data = new byte[BUFSIZE];
while (in.read(data) != -1) {
result += new String(data);
}
} catch (MalformedURLException e) {
cancel(true);
} catch (IOException e) {
cancel(true);
}
return result;
}
#Override
protected void onPostExecute(String result) {
List<String> links = new PageParser(result).getPageLinks();
super.onPostExecute(result);
int rows = listView.getChildCount();
//Add items & update list
for( int i = 0; i < links.size(); i++ )
adapter.add( new Item() );
for( int i = 0; i < links.size(); i++ ){
new PageDownloader(rows+i).execute("http://www.mylink.com/" + links.get(i) );
}
}
}
public class PageDownloader extends AsyncTask<String, Integer, String>{
ProgressBar p;
int row;
public PageDownloader(int row) {
//p is null, I have to comment it out or the program will crash
//p = (ProgressBar) listView.getChildAt( row ).findViewById( R.id.progressBar1 );
this.row = row;
}
#Override
protected String doInBackground(String... params) {
InputStream in = null;
final int BUFSIZE = 1024;
String result = "";
try {
URL url = new URL( params[0] );
URLConnection con = url.openConnection();
con.connect();
in = con.getInputStream();
byte[] data = new byte[BUFSIZE];
while (in.read(data) != -1) {
result += new String(data);
}
} catch (MalformedURLException e) {
cancel(true);
} catch (IOException e) {
cancel(true);
}
return result;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
PageParser parser = new PageParser( result );
//Somehow the list is updated now and the titles will change
listItems.get(row).setTitle( parser.getTitle() );
adapter.notifyDataSetChanged();
//Not Possible because p is always null
//p.setVisibility( ListView.GONE );
}
}

Categories

Resources