Exception in AsyncTask downloading image - android

Refer my question on IllegalStateException in AsyncTask.
I am invoked the following AsyncTask from onPostExecute() of this task(Referred in this link).
public class SaveImageAsync extends AsyncTask<Context, Integer, String> {
private Bitmap bitmap = null;
private ArrayList<String> imageUrls = null;
private ArrayList<ImageView> imageViews = null;
int index = 0;
public SaveImageAsync(ArrayList<ImageView> imageViews,
ArrayList<String> imageUrls) {
this.imageUrls = imageUrls;
this.imageViews = imageViews;
}
#Override
protected String doInBackground(Context... params) {
boolean bRC;
String imageName, imageLocalPath, imageURL;
try {
for (int i = 0; i < imageUrls.size(); i++) {
imageURL = imageUrls.get(i);
String[] strSplittedImagePath = imageURL
.split("/");
if ((strSplittedImagePath != null)
&& (strSplittedImagePath.length >= 1)) {
imageName = strSplittedImagePath[(strSplittedImagePath.length - 1)];
} else {
imageName = imageURL;
}
imageLocalPath = path + imageName;
bRC = doesFileExists(imageLocalPath);
if (bRC == false) {
getImageFromServer(CommonSettings.mSTstrBaseURL
+ imageURL, imageLocalPath);
}
try {
bitmap = BitmapFactory
.decodeFile(imageLocalPath);
} catch (Exception e) {
}
if (bitmap == null) {
try {
new File(imageLocalPath).delete();
} catch (Exception e1) {
}
getImageFromServer(CommonSettings.mSTstrBaseURL
+ imageURL, imageLocalPath);
bitmap = BitmapFactory
.decodeFile(imageLocalPath);
}
Thread.sleep(300);
publishProgress();
}
} catch (InterruptedException e) {
e.printStackTrace();
Log.w(LOG_TAG,
"Got InterruptedException inside AsyncTask SaveImageAsync : "
+ e);
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
ImageView imageView = imageViews.get(index);
while (imageView == null) {
index = index + 1;
imageView = imageViews.get(index);
}
imageView.setScaleType(ScaleType.FIT_XY);
imageView.setImageBitmap(bitmap);
index = index + 1;
//bitmap.recycle();
}
public boolean getImageFromServer(String url, String localPath) {
boolean bReturn = false;
File objNewFile;
try {
objNewFile = new File(localPath);
if (!objNewFile.exists()) {
objNewFile.createNewFile();
}
BufferedInputStream objBufferedInput = new BufferedInputStream(
new java.net.URL(url).openStream());
FileOutputStream objFileOutput = new FileOutputStream(objNewFile);
BufferedOutputStream objBufferOutput = new BufferedOutputStream(
objFileOutput, 1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = objBufferedInput.read(data, 0, 1024)) >= 0) {
objBufferOutput.write(data, 0, x);
}
objFileOutput.flush();
objBufferOutput.flush();
objFileOutput.close();
objBufferOutput.close();
objBufferedInput.close();
bReturn = true;
} catch (IOException e) {
} catch (Exception ex) {
}
return bReturn;
}
}
When pressing back button and loading this task it throws OutOfMemoryException at decodeFile(). Why this happen and how to fix this?
Thanks

Related

generate Gif on Android with AnimatedGifEncoder

i want to create a gif file with AnimatedGifEncoder, its works my gif was created successfully but i can't change the delay between the frames and other settings like quality and so on.
Have any other use this class at android?
Here is my code:
public final class CreateGifUtil extends AbstractAnimatedResource {
private String filename = null;
public CreateGifUtil(Context ctx, List<QueueItem> queueItems) {
super(ctx, queueItems);
}
#Override
public void generate() {
if (!queueItems.isEmpty()) {
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
BufferedOutputStream bs = null;
try {
File mediaSrc = ResourceUtil.getOutputFolder(ctx, ResourceUtil.Folder.IMAGES);
String filename = "test" + String.valueOf(System.currentTimeMillis()) + ".gif";
outputFile = new File(mediaSrc.getAbsolutePath(), filename);
bs = new BufferedOutputStream(new FileOutputStream(outputFile));
encoder.start(bs);
if (isUseFps()) {
encoder.setFrameRate(getFps());
}
encoder.setRepeat(2);
encoder.setQuality(getQuality());
for (QueueItem item : queueItems) {
if (isUseDelayTime()) {
encoder.setDelay(getDelayTime());
}
encoder.addFrame(getBitmapFromResource(item.getFilepath(), 1));
}
boolean result = encoder.finish();
Log.e("123", String.valueOf(result));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (bs != null) {
try {
bs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private Bitmap getBitmapFromResource(String filePath, int sampleSize) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = sampleSize;
return BitmapFactory.decodeFile(filePath, options);
}
}
Here is my code:
package autoshooter.draegerit.de.autoshooter.video;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import autoshooter.draegerit.de.autoshooter.queue.QueueItem;
import autoshooter.draegerit.de.autoshooter.util.ResourceUtil;
public final class CreateGifUtil extends AbstractAnimatedResource {
private String filename = null;
public CreateGifUtil(Context ctx, List<QueueItem> queueItems) {
super(ctx, queueItems);
}
#Override
public void generate() {
if (!queueItems.isEmpty()) {
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
BufferedOutputStream bs = null;
try {
File mediaSrc = ResourceUtil.getOutputFolder(ctx, ResourceUtil.Folder.IMAGES);
String filename = "test" + String.valueOf(System.currentTimeMillis()) + ".gif";
outputFile = new File(mediaSrc.getAbsolutePath(), filename);
bs = new BufferedOutputStream(new FileOutputStream(outputFile));
encoder.start(bs);
if (isUseFps()) {
encoder.setFrameRate(getFps());
}
encoder.setRepeat(2);
encoder.setQuality(getQuality());
for (QueueItem item : queueItems) {
if (isUseDelayTime()) {
encoder.setDelay(getDelayTime());
}
encoder.addFrame(getBitmapFromResource(item.getFilepath(), 1));
}
boolean result = encoder.finish();
Log.e("123", String.valueOf(result));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (bs != null) {
try {
bs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private Bitmap getBitmapFromResource(String filePath, int sampleSize) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = sampleSize;
return BitmapFactory.decodeFile(filePath, options);
}
}
I recommend you to use this Library Android NDK GIF Library it's much better than AnimatedGifEncoder :
and here's a full example of how to generate a GIF file and save it into gallery :
#SuppressLint("StaticFieldLeak")
public class GenerateSaveGIF extends AsyncTask<Void, Integer, String> {
Context mContext;
String imageFileName = "APP_" + System.currentTimeMillis() + ".gif";
ArrayList<BitmapGIFUtil> arrayListBitmaps = new ArrayList<>();
boolean isSavingBitmapsFinished = false;
GenerateSaveGIF(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
//Preparing;
// Display ProgressDialog here
}
#SuppressLint("WrongThread")
#Override
protected String doInBackground(Void... voids) {
File storageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+ "/APP_FOLDER");
boolean success = true;
if (!storageDir.exists()) {
success = storageDir.mkdirs();
}
if (success) {
File imageFile = new File(storageDir, imageFileName);
savedImagePath = imageFile.getAbsolutePath();
FileOutputStream outStream = null;
try {
generateGIF(getArrayBitmaps(), savedImagePath);
} catch (Exception e) {
e.printStackTrace();
}
galleryAddPic(savedImagePath);
}
return savedImagePath;
}
ArrayList<BitmapGIFUtil> getArrayBitmaps() {
for (int i = 0; i < mDrawableGif.getNumberOfFrames(); ++i) {
int GIFDelay = mDrawableGif.getFrameDuration(i); //CHANGE IT IF YOU WANT
try {
Thread.sleep(GIFDelay);
} catch (InterruptedException e) {
e.printStackTrace();
}
//replace createEachFrame() with your method getBitmapFromResource();
arrayListBitmaps.add(new BitmapGIFUtil(createEachFrame(), GIFDelay));
}
isSavingBitmapsFinished = true;
return arrayListBitmaps;
}
void generateGIF(ArrayList<BitmapGIFUtil> arrayList, String path) {
GifEncoder gifEncoder = new GifEncoder();
try {
gifEncoder.init(arrayList.get(0).getBitmap().getWidth(), arrayList.get(0).getBitmap().getHeight(), path, GifEncoder.EncodingType.ENCODING_TYPE_SIMPLE_FAST);
for (int i = 0; i < arrayList.size(); i++) {
gifEncoder.encodeFrame(arrayList.get(i).getBitmap(), arrayList.get(i).getDelay());
}
gifEncoder.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(this, getResources().getString(R.string.gif_saved), Toast.LENGTH_SHORT).show();
}
}
Notify gallery:
private void galleryAddPic(String imagePath) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(imagePath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
BitmapGIFUtil Class:
public class BitmapGIFUtil {
private Bitmap bitmap;
private int Delay;
public BitmapGIFUtil() {
}
public BitmapGIFUtil(Bitmap bitmap, int delay) {
this.bitmap = bitmap;
Delay = delay;
}
public Bitmap getBitmap() {
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public int getDelay() {
return Delay;
}
public void setDelay(int delay) {
Delay = delay;
}
}

Android: white screen while onCreate

I have an app that at launch inside onCreate method copies data from assets folder. It does it in three for cycles, each with activity indicator and the problem is that when first two cycles run white screen shows and only when third loop starts i can seen activity screen with indicator on it.
The code is following
Realm realm;
ListView list;
int[] imageidsm = {R.drawable.fon_sovety350, R.drawable.fon_german350, R.drawable.fon_usa350, R.drawable.fon_uk350, R.drawable.fon_fr_it200, R.drawable.fon_japan_china200, R.drawable.fon_history200};
String[] itemname = {"СССР", "ГЕРМАНИЯ", "США", "ВЕЛИКОБРИТАНИЯ", "ФРАНЦИЯ И ИТАЛИЯ", "ЯПОНИЯ И КИТАЙ", "ИСТОРИЯ"};
Boolean firstLaunch = false;
SharedPreferences preferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
MainAdapter adapter = new MainAdapter(this, itemname, imageidsm, height, width);
list = (ListView) findViewById(R.id.mainListView);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 2) {
Intent toSssr = new Intent(MainActivity.this, TankListActivity.class);
toSssr.putExtra("category", "СССР");
startActivity(toSssr);
} else if (position == 3) {
Intent listActivity = new Intent(MainActivity.this, ArticleListActivity.class);
startActivity(listActivity);
}
}
});
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(this)
.name("db.realm")
.build();
realm.setDefaultConfiguration(realmConfiguration);
realm = Realm.getDefaultInstance();
preferences = getApplicationContext().getSharedPreferences("MyPreferences", Context.MODE_PRIVATE);
firstLaunch = preferences.getBoolean("firstLaunch", false);
if (firstLaunch == false) {
firstLaunch();
}
}
public void firstLaunch() {
String[] arrayOfCatLists = {"00f.json", "01f.json", "02f.json", "10f.json"};
String[] arrayOfArticles = {"32.json", "34.json", "44.json", "51.json", "33.json", "40.json", "41.json", "42.json", "52.json", "45.json", "37.json", "46.json", "36.json", "54.json", "35.json", "43.json", "47.json", "50.json", "49.json", "48.json", "56.json", "58.json", "53.json", "59.json" , "55.json", "60.json", "61.json"};
String[] arrayOfUsssr = {"62.json", "74.json", "75.json", "76.json", "63.json", "78.json", "79.json", "77.json", "81.json", "80.json"};
for (int i = 0; i < arrayOfCatLists.length; i++) {
new GetArticlesListFromDisk(arrayOfCatLists[i], i).execute();
}
for (int i = 0; i < arrayOfArticles.length; i++) {
new GetArticleFromDisk(arrayOfArticles[i]).execute();
}
for (int i = 0; i < arrayOfUsssr.length; i++) {
new GetTanksFromDisk(arrayOfUsssr[i]).execute();
}
firstLaunch = true;
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("firstLaunch", firstLaunch);
editor.apply();
}
private class GetArticlesListFromDisk extends AsyncTask<String, Void, String> {
private String id;
private int index;
String[] arrayOfCatLists = {"00f.json", "01f.json", "02f.json"};
private GetArticlesListFromDisk(String id, int index) {
this.id = id;
this.index = index;
}
ProgressDialog pd = new ProgressDialog(MainActivity.this);
#Override
protected String doInBackground(String... params) {
String json = null;
try {
InputStream input = getApplicationContext().getAssets().open(id);
int size = input.available();
byte[] buffer = new byte[size];
input.read(buffer);
input.close();
json = new String(buffer, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
return json;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pd.setCancelable(false);
pd.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
pd.setMessage("Минуточку, загружаемся");
pd.show();
}
#Override
protected void onPostExecute(String strJson) {
super.onPostExecute(strJson);
pd.dismiss();
JSONObject dataJsonObj = null;
String category = "";
try {
dataJsonObj = new JSONObject(strJson);
JSONArray listing = dataJsonObj.getJSONArray("listing");
for (int i = 0; i < listing.length(); i++) {
JSONObject object = listing.getJSONObject(i);
String id = object.getString("id");
String title = object.getString("title");
String subtitle = object.getString("subtitle");
String image = object.getString("image");
InputStream inputStream =null;
Bitmap bitmap = null;
try {
inputStream = getAssets().open(image);
bitmap = BitmapFactory.decodeStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
Log.d("getArticleFromDisk", "Saved article " + title);
ImageStorage.saveToSdCard(bitmap, image, getApplicationContext());
if (index == 0) {
category = "Танковые сражения";
} else if (index == 1) {
category = "Справочник танкиста";
} else if (index == 2) {
category = "Танковые асы";
} else if (index == 3) {
category = "СССР";
} else if (index == 4) {
category = "Германия";
} else if (index == 5) {
category = "США";
} else if (index == 6) {
category = "Великобритания";
}
realm.beginTransaction();
ArticleList articleList = realm.createObject(ArticleList.class);
articleList.setId(id);
articleList.setTitle(title);
articleList.setSubtitle(subtitle);
articleList.setImage(image);
articleList.setCategory(category);
realm.commitTransaction();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private class GetArticleFromDisk extends AsyncTask<String, Void, String> {
private String id;
private int categoryIndex;
private GetArticleFromDisk(String id) {
this.id = id;
}
public String LOG_TAG = "GetArticleFromDisk";
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String resultJson = "";
ProgressDialog pd = new ProgressDialog(MainActivity.this);
#Override
protected String doInBackground(String... params) {
String json = null;
try {
InputStream input = getApplicationContext().getAssets().open(id);
int size = input.available();
byte[] buffer = new byte[size];
input.read(buffer);
input.close();
json = new String(buffer, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
return json;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pd.setCancelable(false);
pd.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
pd.setMessage("Минуточку, загружаемся");
pd.show();
}
#Override
protected void onPostExecute(String strJson) {
super.onPostExecute(strJson);
pd.dismiss();
JSONObject dataJsonObj = null;
String category = "";
try {
dataJsonObj = new JSONObject(strJson);
JSONArray listing = dataJsonObj.getJSONArray("article");
for (int i = 0; i < listing.length(); i++) {
JSONObject object = listing.getJSONObject(i);
String id = object.getString("id");
String title = object.getString("title");
String subtitle = object.getString("subtitle");
String body = object.getString("body");
String hash = object.getString("content_version");
Log.d(LOG_TAG, "Saved article with id " + id);
realm.beginTransaction();
Article article = realm.createObject(Article.class);
article.setId(id);
article.setTitle(title);
article.setSubtitle(subtitle);
article.setBody(body);
article.setHash(hash);
realm.commitTransaction();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private class GetTanksFromDisk extends AsyncTask<String, Void, Tank> {
private String id;
private int categoryIndex;
private GetTanksFromDisk(String id) {
this.id = id;
}
public String LOG_TAG = "GetTankFromDisk";
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String resultJson = "";
ProgressDialog pd = new ProgressDialog(MainActivity.this);
Tank tank = new Tank();
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.d(LOG_TAG, "Entered preExecute");
pd.setCancelable(false);
pd.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
pd.setMessage("Минуточку, загружаемся");
pd.show();
}
#Override
protected Tank doInBackground(String... params) {
String json = null;
try {
InputStream input = getApplicationContext().getAssets().open(id);
int size = input.available();
byte[] buffer = new byte[size];
input.read(buffer);
input.close();
json = new String(buffer, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
JSONObject dataJsonObj = null;
String category = "";
try {
dataJsonObj = new JSONObject(json);
JSONArray listing = dataJsonObj.getJSONArray("article");
for (int i = 0; i < listing.length(); i++) {
JSONObject object = listing.getJSONObject(i);
String id = object.getString("id");
String title = object.getString("title");
JSONArray signatures = object.getJSONArray("signatures");
ArrayList<String> signatures_list = new ArrayList<String>();
for (int j = 0; j < signatures.length(); j++) {
signatures_list.add(signatures.get(j).toString());
}
String signatures_string = Joiner.on(",").join(signatures_list);
String body = object.getString("body");
String construction = object.getString("construction");
String modification = object.getString("modification");
String ttx = object.getString("ttx");
JSONObject images = object.getJSONObject("images");
JSONArray tank_slider = images.getJSONArray("tank_slider");
ArrayList<String> tank_slider_list = new ArrayList<String>();
for (int k = 0; k < tank_slider.length(); k++) {
InputStream inputStream =null;
Bitmap bitmap = null;
try {
inputStream = getAssets().open(tank_slider.getString(k));
bitmap = BitmapFactory.decodeStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
ImageStorage.saveToSdCard(bitmap, tank_slider.getString(k), getApplicationContext());
tank_slider_list.add(tank_slider.getString(k));
}
String tank_slider_string = Joiner.on(",").join(tank_slider_list);
String hash = object.getString("content_version");
Log.d(LOG_TAG, "Imported from assets tank with id " + id);
tank.setId(id);
tank.setTitle(title);
tank.setSignatures(signatures_string);
tank.setBody(body);
tank.setConstruction(construction);
tank.setModification(modification);
tank.setTtx(ttx);
tank.setTank_slider(tank_slider_string);
tank.setHash(hash);
}
} catch (JSONException e) {
e.printStackTrace();
}
return tank;
}
#Override
protected void onPostExecute(Tank tank) {
super.onPostExecute(tank);
pd.dismiss();
realm.beginTransaction();
Tank newTank = realm.createObject(Tank.class);
newTank.setId(tank.getId());
newTank.setTitle(tank.getTitle());
newTank.setSignatures(tank.getSignatures());
newTank.setBody(tank.getBody());
newTank.setConstruction(tank.getConstruction());
newTank.setModification(tank.getModification());
newTank.setTtx(tank.getTtx());
newTank.setTank_slider(tank.getTank_slider());
newTank.setHash(tank.getHash());
realm.commitTransaction();
}
}
What Im I doing wrong ?

Android FileOutputStream FileInputStream issue

I have set up a activity on my app that creates a new high score then saves it and allows it to be reloaded and display through FileOutputStream and FileInputStream logic. I have been testing the app on my phone and when loading the high score back I am getting 0 returned. I believe this is because there are zero bytes within the file.
Heres all my code:
public class Course extends ActionBarActivity {
String chosenCourseValue = "";
int courseNum;
String listPars = "";
String listHoles = "";
String courseImage = "";
int[] scoreNum = new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int totalScoreNum = 0;
String collected = "test string";
public void upButtonOnClick(View imageButton)
{
int textViewId = getResources().getIdentifier((String) imageButton.getTag(), "id", getPackageName());
TextView score = (TextView) findViewById(textViewId);
totalScoreNum++;
if (score.getId() == R.id.score1)
{
scoreNum[0]++;
score.setText(String.valueOf(scoreNum[0]));
}
if (score.getId() == R.id.score2)
{
scoreNum[1]++;
score.setText(String.valueOf(scoreNum[1]));
}
if (score.getId() == R.id.score3)
{
scoreNum[2]++;
score.setText(String.valueOf(scoreNum[2]));
}
if (score.getId() == R.id.score4)
{
scoreNum[3]++;
score.setText(String.valueOf(scoreNum[3]));
}
if (score.getId() == R.id.score5)
{
scoreNum[4]++;
score.setText(String.valueOf(scoreNum[4]));
}
if (score.getId() == R.id.score6)
{
scoreNum[5]++;
score.setText(String.valueOf(scoreNum[5]));
}
if (score.getId() == R.id.score7)
{
scoreNum[6]++;
score.setText(String.valueOf(scoreNum[6]));
}
if (score.getId() == R.id.score8)
{
scoreNum[7]++;
score.setText(String.valueOf(scoreNum[7]));
}
if (score.getId() == R.id.score9)
{
scoreNum[8]++;
score.setText(String.valueOf(scoreNum[8]));
}
if (score.getId() == R.id.score10)
{
scoreNum[9]++;
score.setText(String.valueOf(scoreNum[9]));
}
if (score.getId() == R.id.score11)
{
scoreNum[10]++;
score.setText(String.valueOf(scoreNum[10]));
}
if (score.getId() == R.id.score12)
{
scoreNum[11]++;
score.setText(String.valueOf(scoreNum[11]));
}
if (score.getId() == R.id.score13)
{
scoreNum[12]++;
score.setText(String.valueOf(scoreNum[12]));
}
if (score.getId() == R.id.score14)
{
scoreNum[13]++;
score.setText(String.valueOf(scoreNum[13]));
}
if (score.getId() == R.id.score15)
{
scoreNum[14]++;
score.setText(String.valueOf(scoreNum[14]));
}
if (score.getId() == R.id.score16)
{
scoreNum[15]++;
score.setText(String.valueOf(scoreNum[15]));
}
if (score.getId() == R.id.score17)
{
scoreNum[16]++;
score.setText(String.valueOf(scoreNum[16]));
}
if (score.getId() == R.id.score18)
{
scoreNum[17]++;
score.setText(String.valueOf(scoreNum[17]));
}
}
public void downButtonOnClick(View imageButton)
{
int textViewId = getResources().getIdentifier((String) imageButton.getTag(), "id", getPackageName());
TextView score = (TextView) findViewById(textViewId);
totalScoreNum--;
if (score.getId() == R.id.score1)
{
scoreNum[0]--;
score.setText(String.valueOf(scoreNum[0]));
}
if (score.getId() == R.id.score2)
{
scoreNum[1]--;
score.setText(String.valueOf(scoreNum[1]));
}
if (score.getId() == R.id.score3)
{
scoreNum[2]--;
score.setText(String.valueOf(scoreNum[2]));
}
if (score.getId() == R.id.score4)
{
scoreNum[3]--;
score.setText(String.valueOf(scoreNum[3]));
}
if (score.getId() == R.id.score5)
{
scoreNum[4]--;
score.setText(String.valueOf(scoreNum[4]));
}
if (score.getId() == R.id.score6)
{
scoreNum[5]--;
score.setText(String.valueOf(scoreNum[5]));
}
if (score.getId() == R.id.score7)
{
scoreNum[6]--;
score.setText(String.valueOf(scoreNum[6]));
}
if (score.getId() == R.id.score8)
{
scoreNum[7]--;
score.setText(String.valueOf(scoreNum[7]));
}
if (score.getId() == R.id.score9)
{
scoreNum[8]--;
score.setText(String.valueOf(scoreNum[8]));
}
if (score.getId() == R.id.score10)
{
scoreNum[9]--;
score.setText(String.valueOf(scoreNum[9]));
}
if (score.getId() == R.id.score11)
{
scoreNum[10]--;
score.setText(String.valueOf(scoreNum[10]));
}
if (score.getId() == R.id.score12)
{
scoreNum[11]--;
score.setText(String.valueOf(scoreNum[11]));
}
if (score.getId() == R.id.score13)
{
scoreNum[12]--;
score.setText(String.valueOf(scoreNum[12]));
}
if (score.getId() == R.id.score14)
{
scoreNum[13]--;
score.setText(String.valueOf(scoreNum[13]));
}
if (score.getId() == R.id.score15)
{
scoreNum[14]--;
score.setText(String.valueOf(scoreNum[14]));
}
if (score.getId() == R.id.score16)
{
scoreNum[15]--;
score.setText(String.valueOf(scoreNum[15]));
}
if (score.getId() == R.id.score17)
{
scoreNum[16]--;
score.setText(String.valueOf(scoreNum[16]));
}
if (score.getId() == R.id.score18)
{
scoreNum[17]--;
score.setText(String.valueOf(scoreNum[17]));
}
}
class AsyncAPI extends AsyncTask<Void, Void, String>
{
#Override
protected String doInBackground(Void... arg0)
{
String JSONString = null;
try
{
//hard coded url API from website
String urlString = "http://webthree.ict.op.ac.nz/murraas1/golf.html";
//converting url string to object then sending (same as pressing return)
URL URLObject = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) URLObject.openConnection();
connection.connect();
//if it doesnt return 200 no data received. (use if statement to check in future)
int responseCode = connection.getResponseCode();
//getting inputstream from the sent object and setting up bufferreader
InputStream inputStream = connection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
//reading the input
String responseString;
StringBuilder stringBuilder = new StringBuilder();
while ((responseString = bufferedReader.readLine()) != null)
{
stringBuilder = stringBuilder.append(responseString);
}
//getting string from stringbuilder and converting to a json string
JSONString = stringBuilder.toString();
}
catch (Exception e){e.printStackTrace();}
return JSONString;
}
protected void onPostExecute(String fetchedString)
{
String selectedCourse = "";
String totalPar = "";
if (chosenCourseValue.equals("Chisholm"))
{
courseNum = 0;
courseImage = "chisolm";
}
if (chosenCourseValue.equals("St Clair"))
{
courseNum = 1;
courseImage = "stclair";
}
if (chosenCourseValue.equals("Balmacewen"))
{
courseNum = 2;
courseImage = "balmacewen";
}
if (chosenCourseValue.equals("Taieri"))
{
courseNum = 3;
courseImage = "taieri";
}
if (chosenCourseValue.equals("Island Park"))
{
courseNum = 4;
courseImage = "islandpark";
}
try {
JSONObject root = new JSONObject(fetchedString);
JSONArray courseArray = root.getJSONArray("courses");
JSONObject courseInfo = courseArray.getJSONObject(courseNum);
selectedCourse = (courseInfo.getString("name"));
totalPar = (courseInfo.getString("course par"));
JSONArray parsInfo = courseInfo.getJSONArray("pars");
for(int i = 0; i < parsInfo.length(); i++)
{
JSONObject parsNum = parsInfo.getJSONObject(i);
listPars += ("Par " + parsNum.getString("par") + ",");
}
JSONArray holesInfo = courseInfo.getJSONArray("pars");
for(int i = 0; i < holesInfo.length(); i++)
{
JSONObject holeNum = holesInfo.getJSONObject(i);
listHoles += (holeNum.getString("hole") + ",");
}
}
catch (JSONException e) {
e.printStackTrace();
}
//Convert Pars and Holes text into usable array
String[] listParsArray = listPars.split(",");
String[] listHolesArray = listHoles.split(",");
//dumping Name into textview
TextView tv = (TextView) findViewById(R.id.courseName);
tv.setText(selectedCourse);
//dumping Total Par into textview
TextView tv1 = (TextView) findViewById(R.id.totalPar);
tv1.setText(totalPar);
//dumping Pars into textview
int[] parViewIDs = new int[] {R.id.hole1Par, R.id.hole2Par, R.id.hole3Par, R.id.hole4Par, R.id.hole5Par, R.id.hole6Par, R.id.hole7Par, R.id.hole8Par, R.id.hole9Par, R.id.hole10Par, R.id.hole11Par, R.id.hole12Par, R.id.hole13Par, R.id.hole14Par, R.id.hole15Par, R.id.hole16Par, R.id.hole17Par, R.id.hole18Par,};
for(int i = 0; i < 18; i++) {
TextView tv2 = (TextView) findViewById(parViewIDs[i]);
tv2.setText(listParsArray[i]);
}
//dumping Holes into textview
int[] holeViewIDs = new int[] {R.id.hole1, R.id.hole2, R.id.hole3, R.id.hole4, R.id.hole5, R.id.hole6, R.id.hole7, R.id.hole8, R.id.hole9, R.id.hole10, R.id.hole11, R.id.hole12, R.id.hole13, R.id.hole14, R.id.hole15, R.id.hole16, R.id.hole17, R.id.hole18,};
for(int i = 0; i < 18; i++)
{
TextView tv3 = (TextView) findViewById(holeViewIDs[i]);
tv3.setText(listHolesArray[i]);
}
int[] images = {R.drawable.chisholm, R.drawable.stclair, R.drawable.balmacewen, R.drawable.taieri, R.drawable.islandpark};
ImageView i = (ImageView) findViewById(R.id.courseImage);
i.setImageResource(images[courseNum]);
}
}
private void updateTextView() {
TextView tv3 = (TextView) findViewById(R.id.totalScore);
tv3.setText(String.valueOf(totalScoreNum));
}
public class SaveData implements View.OnClickListener
{
//String totalScoreString = String.valueOf(totalScoreNum);
#Override
public void onClick(View v) {
try {
FileOutputStream fou = openFileOutput("scoreFile.txt", Context.MODE_PRIVATE);
fou.write(totalScoreNum);
fou.close();
// Toast Confirm
Toast.makeText(Course.this, "Success", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void loadData()
{
FileInputStream fis = null;
try {
fis = openFileInput("scoreFile.txt");
byte[] dataArray = new byte[fis.available()];
while (fis.read(dataArray) != -1){
collected = new String(dataArray);
}
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public class LoadData implements View.OnClickListener
{
#Override
public void onClick(View v) {
TextView tv7 = (TextView) findViewById(R.id.returnScore);
tv7.setText(collected);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_course);
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
updateTextView();
}
});
}
} catch (InterruptedException e) {
}
}
};
loadData();
t.start();
Button SaveDataBtn = (Button)findViewById(R.id.saveScore);
SaveData handler = new SaveData();
SaveDataBtn.setOnClickListener (handler);
Button LoadDataBtn = (Button)findViewById(R.id.loadScore);
LoadData handler1 = new LoadData();
LoadDataBtn.setOnClickListener (handler1);
Bundle extras = getIntent().getExtras();
if (extras != null) {
chosenCourseValue = extras.getString("passedChosenCourse");
}
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
AsyncAPI APIThread = new AsyncAPI();
APIThread.execute();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
Heres the FileOutputStream FileInputStream where i believe the problem lies:
public class SaveData implements View.OnClickListener
{
//String totalScoreString = String.valueOf(totalScoreNum);
#Override
public void onClick(View v) {
try {
FileOutputStream fou = openFileOutput("scoreFile.txt", Context.MODE_PRIVATE);
fou.write(totalScoreNum);
fou.close();
// Toast Confirm
Toast.makeText(Course.this, "Success", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void loadData()
{
FileInputStream fis = null;
try {
fis = openFileInput("scoreFile.txt");
byte[] dataArray = new byte[fis.available()];
while (fis.read(dataArray) != -1){
collected = new String(dataArray);
}
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
When first running the app loading back the score will return the string "test string" which it was initially populated with, but once a actual score is loaded and saved it will return "0". Any help or explanation would be appreciated!
Have you tried supplying a full path for the input and output stream?
For example "/sdcard/Downloads/myapp/scoreFile.txt"
Also don't hardcode the path, use Environment.getExternalStorageDirectory(), I think this will return a File object or string path equal to "/sdcard/"
Don't forgot to add permissions for the external read and write

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.

Android: Custom ListView and Threading problem

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);
}
}

Categories

Resources