Multiple asynchronous tasks in Android App - android

I have a strange problem. I'm developing an Android app which has 3 independent Async Tasks. When I try to run the app on a quad core phone there is no problem. But if I try to run the app on a dual core phone app crashes. How can I modify my tasks for dual core phones ?
Here is my code
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
This is the first async task. The second one is the Parse.com file upload async saveInBackground method.
public void startUpload(String fileName) {
try {
photoFile = new ParseFile(fileName, scaledData);
if (isTac) {
pictures.setPhotoFileTac(photoFile);
} else if (isCanak) {
pictures.setPhotoFileCanak(photoFile);
} else if (isYaprak) {
pictures.setPhotoFileYaprak(photoFile);
}
// pictures.save();// Telefon çekirdeğine göre 2 asenkron methodu desteklemiyor o yüzden sadece save yazılabilir fakat başarılı kontolü SaveCallback' te yakalanamaz.
pictures.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if(e == null){
Toast.makeText(getApplicationContext(),"Buluta yükleme başarılı. " , Toast.LENGTH_LONG).show();
if(pdialog != null)
{
pdialog.dismiss();//Eğer işlem başarılı ise asenkron sınıfta yaratılan progressbar ı kapat.
}
}
else{
Toast.makeText(getApplicationContext(),"Hata" +e.toString(),Toast.LENGTH_LONG).show();
}
}
});
}
catch (Exception ex)
{
Toast.makeText(getApplicationContext(),"Bağlantı Hatası !",Toast.LENGTH_LONG).show();
}
}
And the third one is the progress bar of upload process.
public class AsyncUpload extends AsyncTask<String,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pdialog = new ProgressDialog(TakePictureActivity.this);
pdialog.setMessage("Yükleniyor...");
pdialog.setIndeterminate(false);
pdialog.setCancelable(false);
pdialog.show();
}
#Override
protected String doInBackground(String... fileNames) {
return fileNames[0];
}
#Override
protected void onPostExecute(String name) {
startUpload(name);
super.onPostExecute(name);
}
}
And there is the code where I initialize upload session. (In if - else condition states the line new AsyncUpload().execute(fileName);
private void saveScaledPhoto(byte[] data) {
// Resize photo from camera byte array
pictureWidth = camera.getParameters().getPictureSize().width;
pictureHeight = camera.getParameters().getPictureSize().height;
Bitmap plantImage = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap plantImageScaled = Bitmap.createScaledBitmap(plantImage, pictureWidth, pictureHeight, false);
pictureCache = new PictureCache();
// Override Android default landscape orientation and save portrait
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedScaledPlantImage = Bitmap.createBitmap(plantImageScaled, 0,
0, plantImageScaled.getWidth(), plantImageScaled.getHeight(),
matrix, true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
rotatedScaledPlantImage.compress(Bitmap.CompressFormat.PNG, 100, bos);
scaledData = bos.toByteArray();
AlertDialog.Builder aDB = new AlertDialog.Builder(this);
aDB.setCancelable(false);
aDB.setTitle("Emin misiniz ?");
aDB.setMessage("Çektiğiniz resim analizde kullanılacaktır. Devam etmek istiyor musunuz ?.. ");
aDB.setPositiveButton("Evet", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (isTac) {
pictureCache.setByteArrayTac(scaledData);
isTac = false;
isCanak = true;
Toast.makeText(getApplicationContext(), "Taç yaprak görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "TacYaprak";
new AsyncUpload().execute(fileName);
} else if (isCanak) {
pictureCache.setByteArrayCanak(scaledData);
isCanak = false;
isYaprak = true;
Toast.makeText(getApplicationContext(), "Çanak yaprak görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "CanakYaprak";
new AsyncUpload().execute(fileName);
} else if (isYaprak) {
String plantTag = "A_Y";
pictureCache.setByteArrayYaprak(scaledData);
isYaprak = false;
Toast.makeText(getApplicationContext(), "Ağaç yaprağı görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "AgacYapragi";
new AsyncUpload().execute(fileName);
}
if (!isTac && !isCanak && !isYaprak) {
finish();
}
}
});
aDB.setNegativeButton("Hayır", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alertDialog = aDB.create();
alertDialog.show();
}
Here is the logcat output..
java.lang.NullPointerException
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:482)
at com.altygtsoft.biomatch.TakePictureActivity.saveScaledPhoto(TakePictureActivity.java:202)
at com.altygtsoft.biomatch.TakePictureActivity.access$000(TakePictureActivity.java:45)
at com.altygtsoft.biomatch.TakePictureActivity$2$1$2.onPictureTaken(TakePictureActivity.java:147)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:855)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5371)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)

Just realized my idea is too big for a comment so->
What happens if you do the following?
//Beware pseudo-code
new AsyncTask<>({
onPreExecute(){
//keep your code from before
...
}
doInBackground(Params... params){
startUpload(params[0], params[1]); //minus the done() function, plus pictures?
}
onPostExecute(){
//As I'm not sure where it fits in, if possible execute done() here.
}
}).execute(fileName, pictures); //couldn't find the decleration of pictures, so I stole the decleration of independence instead. Also maybe you need to put pictures in there, depending on where it is and how public/static.

Related

Tesseract in android (Tess Two): Application crashes while using nep.traineddata and Input from Camera is not working

I am not much of an expert.I am using tesseract (tess-two) for developing an android application for my college project. The application crashes when I select the Nepali trained data.
*The application works only with Image selected from gallery. The image taken from camera returns empty result. So, yes! I am in big trouble here!!
Here is the snippet of the LogCat when I used eng.trainddata:
04-26 22:52:02.286 26503-26509/com.l.android.neptext I/zygote64: Do partial code cache collection, code=124KB, data=69KB
After code cache collection, code=124KB, data=69KB
Increasing code cache capacity to 512KB
04-26 22:52:02.347 26503-26520/com.l.android.neptext I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8996.so from the current namespace instead.
04-26 22:52:08.559 26503-26503/com.l.android.neptext D/com.l.android.neptext.MainActivity$3#2314718: onClick:
04-26 22:52:08.612 26503-26503/com.l.android.neptext D/AppTracker: App Event: stop
04-26 22:52:21.431 26503-26503/com.l.android.neptext D/AppTracker: App Event: start
04-26 22:52:21.603 26503-26589/com.l.android.neptext I/com.l.android.neptext.MainActivity$5#8074bd5: bitmap size8294400
04-26 22:52:22.232 26503-26589/com.l.android.neptext I/Tesseract(native): Initialized Tesseract API with language=eng
04-26 22:52:35.031 26503-26509/com.l.android.neptext I/zygote64: Compiler allocated 6MB to compile void android.view.ViewRootImpl.performTraversals()
04-26 22:52:39.452 26503-26503/com.l.android.neptext D/AppTracker: App Event: stop
Another snippet when I use nep.traineddata:
04-26 22:53:44.007 26764-26769/com.l.android.neptext I/zygote64: Compiler allocated 6MB to compile void android.view.ViewRootImpl.performTraversals()
04-26 22:53:44.095 26764-26780/com.l.android.neptext D/OpenGLRenderer: endAllActiveAnimators on 0x7e841e2000 (DropDownListView) with handle 0x7e7abf6840
04-26 22:53:46.978 26764-26764/com.l.android.neptext D/com.l.android.neptext.MainActivity$3#cc3f660: onClick:
04-26 22:53:47.033 26764-26764/com.l
.android.neptext D/AppTracker: App Event: stop
04-26 22:54:00.276 26764-26764/com.l.android.neptext D/AppTracker: App Event: start
04-26 22:54:00.449 26764-26815/com.l.android.neptext I/com.l.android.neptext.MainActivity$5#c8be754: bitmap size8294400
The app crashes without other error message.
Code of Project:
public class MainActivity extends AppCompatActivity {
public static Button camera,gallery,cut,copy,speech;
public static EditText text;
public static TextView textView;
public static final int GALERY_ACTION=100;
public static final int CAMERA_ACTION=101;
public static Uri imageuri=null;
Handler texthandler;
TextToSpeech t1;
Spinner spinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
camera=findViewById(R.id.button1);
gallery=findViewById(R.id.button2);
cut=findViewById(R.id.cut_btn);
copy=findViewById(R.id.copy_btn);
speech=findViewById(R.id.speech_btn);
text = findViewById(R.id.result_text);
textView=findViewById(R.id.textView);
spinner=findViewById(R.id.spinner);
spinner=findViewById(R.id.spinner);
List<String> categories = new ArrayList<String>();
categories.add("eng");
categories.add("nep");
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, categories);
// Drop down layout style - list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinner.setAdapter(dataAdapter);
t1=new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
t1.setLanguage(Locale.UK);
}
}
});
texthandler=new Handler(Looper.myLooper()){
#Override
public void handleMessage(Message msg) {
String t=(String)msg.obj;
if(t==null){
Toast.makeText(getApplicationContext(),"Cannot find any letters ",Toast.LENGTH_LONG).show();
}
text = findViewById(R.id.result_text);
text.setText((String)msg.obj);
}
};
onButtonClickListiner();
//copying tranning datas
try {
MainApplication.instance.copydata("eng");
MainApplication.instance.copydata("nep");
}catch(Exception e){
Log.d("OcrManager",e.getMessage());
}
}
public void copy(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
ClipboardManager clipboardManager=(ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData=ClipData.newPlainText("label",text.getText().toString());
clipboardManager.setPrimaryClip(clipData);
Toast.makeText(MainActivity.this,"Text copied to clipbaord",Toast.LENGTH_LONG).show();
}
public void cut(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
ClipboardManager clipboardManager=(ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData=ClipData.newPlainText("label",text.getText().toString());
clipboardManager.setPrimaryClip(clipData);
text.setText("");
Toast.makeText(MainActivity.this,"Text copied to clipbaord",Toast.LENGTH_LONG).show();
}
public void speech(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
t1.speak(text.getText().toString(),TextToSpeech.QUEUE_FLUSH,null,null);
} else {
t1.speak(text.getText().toString(), TextToSpeech.QUEUE_FLUSH, null);
}
Toast.makeText(this,"Speaking now",Toast.LENGTH_LONG).show();
}
private void onButtonClickListiner(){
gallery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
Log.d(this.toString(), "onClick: ");
Intent galaryIntent=new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(galaryIntent,GALERY_ACTION);
gallery.setVisibility(View.GONE);
camera.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
cut.setVisibility(View.VISIBLE);
copy.setVisibility(View.VISIBLE);
speech.setVisibility(View.VISIBLE);
text.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);
}catch(Exception e){
Log.d("Main actiity",e.getMessage());
}
}
});
camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
Intent cameraIntent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent,CAMERA_ACTION);
gallery.setVisibility(View.GONE);
camera.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
cut.setVisibility(View.VISIBLE);
copy.setVisibility(View.VISIBLE);
speech.setVisibility(View.VISIBLE);
text.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);
}catch(Exception e){
Log.d("Main actiity",e.getMessage());
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
if (resultCode == RESULT_OK && data != null) {
if (requestCode == GALERY_ACTION) {
imageuri = data.getData();
try {
MainApplication.instance.showToast("Rendering Started,Please wait");
new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageuri);
Log.i(this.toString(),"bitmap size"+bitmap.getByteCount());
OcrManager ocrManager= new OcrManager();
ocrManager.ocrStart(spinner.getSelectedItem().toString());
final String s = ocrManager.getText(bitmap);
Message m = new Message();
m.obj = s;
texthandler.sendMessage(m);
} catch (Exception e) {
Log.e("Main actiity", e.getMessage());
}
}
}).start();
} catch (Exception e) {
Log.d(this.toString(), e.getMessage());
}
}else if(requestCode==CAMERA_ACTION){
try {
MainApplication.instance.showToast("Rendering Started,Please wait");
new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
try {
Bundle bundle=data.getExtras();
Bitmap bitmap = (Bitmap)bundle.get("data");
OcrManager ocrManager= new OcrManager();
ocrManager.ocrStart(spinner.getSelectedItem().toString());
final String s = ocrManager.getText(bitmap);
Message m = new Message();
m.obj = s;
texthandler.sendMessage(m);
} catch (Exception e) {
Log.d("Main actiity", e.getMessage());
}
}
}).start();
} catch (Exception e) {
Log.d(this.toString(), e.getMessage());
}
}
}
}
}
OCRManager Class:
public class OcrManager {
public static TessBaseAPI base=null;
public void ocrStart(String lang) {
try{
base = new TessBaseAPI();
String dataDirectory = MainApplication.instance.tessDataPathParent();
base.init(dataDirectory, lang);
}catch(Exception e){}
}
public String getText(Bitmap bitmap){
base.setImage(bitmap);
MainApplication.instance.showToast("Conversion Started");
String out=base.getUTF8Text();
MainApplication.instance.showToast("Conversion finished");
return out;
}
}
Also there is another class which copies nepali and english trained data to the storage successfully.
So, what am I doing wrong here? There is no any result when camera is used and the app crashes when nepali trained data is used with gallery source. Please help me out here. I do not want to do this again in resit.
So the other thing I had done wrong was the value of dataDirectory and just changing its value made the application a lot stable. The nep.trained data was found and initialized by the tesseract after that.
private static final String dataDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/com.lokensapkota.android.neptext/";
Also, if I changed the whole function in MainApplication class; which was just there to copy the trained data, to a method and ran it in background.:
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("trainneddata");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
for(String filename : files) {
Log.i("files",filename);
InputStream in = null;
OutputStream out = null;
String dirout= dataDirectory + "tessdata/";
File outFile = new File(dirout, filename);
if(!outFile.exists()) {
try {
in = assetManager.open("trainneddata/"+filename);
(new File(dirout)).mkdirs();
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (IOException e) {
Log.e("tag", "Error creating files", e);
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
Even though the the previous MainApplication.class copied both english and nepali trained data to the app directory, the nep.traineddata failed to initialized. this method, however did the same thing but it made things work.

Threading requires that an application's button be clicked twice

I have the following code. submitClick() is triggered when someone clicks the submit button on my application. In the past, submit click would be click once, and all of submitFile() would be carried out. By adding the threading addition to checkContent(), now submitClick has to be clicked twice for all of submitFile() to be completed. Is there any way to make it so that submitFile() finishes (with checkContent()) so the user only has to press my apps submit button?
Thank you in advance.
public void submitClick(View v) throws Exception{
if (!submitted) { submitFile(); }
}
public void submitFile() {
checkContent();
if (valid) {
Picasso.with(this).load(imageAddress).into(imagePreview);
saveImage();
//sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); //refreshes system to show saved file
submitted = true;
submit_but.setText("Encrypt");
}
}
private void checkContent() {
media = null;
if(URLUtil.isValidUrl(imageAddress)) {
Thread thread = new Thread() {
boolean img = false;
boolean youtube = false;
public void run() {
URLConnection connection = null;
try {
connection = new URL(imageAddress).openConnection();
} catch (IOException e) {
e.printStackTrace();
}
String contentType = connection.getHeaderField("Content-Type");
img = contentType.startsWith("image/");
if(img)
media = "image";
if (!img) {
// Check host of url if youtube exists
Uri uri = Uri.parse(imageAddress);
if ("www.youtube.com".equals(uri.getHost())) {
media = "youtube";
youtube = true;
}
}
valid = img || youtube;
}
};
thread.start();
}
}
The problem is that the Thread will finish after the call to if (valid) and the rest in the submitFile().
Easy fix is to include the entire submitFile() in a Thread, instead of just part of it. If the logic is bound to each other, it's better off that they're together.
A more android-esque fix is to use AsyncTask, as such:
public void submitClick(View v) throws Exception {
if (!submitted) { submitFile(); }
}
public void submitFile() {
if(URLUtil.isValidUrl(imageAddress)) {
new AsyncTask<Void, Void, Boolean>() {
protected Long doInBackground(Void... voids) {
boolean img = false;
boolean youtube = false;
URLConnection connection = null;
try {
connection = new URL(imageAddress).openConnection();
} catch (IOException e) {
e.printStackTrace();
}
String contentType = connection.getHeaderField("Content-Type");
img = contentType.startsWith("image/");
if(img)
media = "image";
if (!img) {
// Check host of url if youtube exists
Uri uri = Uri.parse(imageAddress);
if ("www.youtube.com".equals(uri.getHost())) {
media = "youtube";
youtube = true;
}
}
return img || youtube;
}
protected void onPostExecute(Boolean valid) {
if (valid) {
Picasso.with(this).load(imageAddress).into(imagePreview);
saveImage();
//sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); //refreshes system to show saved file
submitted = true;
submit_but.setText("Encrypt");
}
}
}.execute();
}
}

Android: AsyncTask crashing app

I have problem in my application.
I want to show user's profile, and I have two links in my app.
One link is via TextView, which run showUser(View v) method:
public void showUser(View v){
Intent i;
i=new Intent(getApplicationContext(), ShowProfile.class);
i.putExtra("id",user); // user is String with users ID
startActivity(i);
}
And the second link is in dialog, which user can open:
( I will post here whole method, but I'll highlight important part )
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder .setTitle(R.string.show_photo_show_rated_users_title)
.setNegativeButton("Close", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
ListView modeList = new ListView(this);
String[] stringArray = new String[ratedUsers.size()];
for ( int i=0 ; i<ratedUsers.size() ; i++ ){
stringArray[i] = ratedUsers.get(i).get("name");
}
ArrayAdapter<String> modeAdapter = new ArrayAdapter<String>(this, R.layout.dropdown_item_white, android.R.id.text1, stringArray);
modeList.setAdapter(modeAdapter);
modeList.setOnItemClickListener(new ListView.OnItemClickListener(){
/*********************** IMPORTANT PART *********************************/
#Override
public void onItemClick(AdapterView<?> parent, View arg1, int index,long arg3) {
Intent i;
i=new Intent(ShowPhotoDetails.this , ShowProfile.class);
i.putExtra("id",ratedUsers.get(index).get("id"));
/**** ratedUsers is ArrayList<HashMap<String,String>> ****/
startActivity(i);
}});
builder.setView(modeList);
final Dialog dialog = builder.create();
dialog.show();
}
And finally here's ShowProfile.class:
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.profile);
Intent i = getIntent();
try {
id = i.getStringExtra("id");
}catch(Exception e){
e.printStackTrace();
Toast.makeText(getBaseContext(), "Error loading intent", Toast.LENGTH_SHORT).show();
finish();
}
try{
Log.w("ID",id); //always give right number
new GetUserInformations().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, id);
/*
If I comments this asyncTask, there's no error at all, but if I run it, It
open debug View in Eclipse, says that "Source not found" and crashes...
No LogCat Output
*/
}catch(Exception e){
e.printStackTrace();
}
...
I wonder why in one case it run perfectly and in the other it crashes. As I wrote in code, there's no LogCat output for this crash. It don't even say Uncaught exception or something like this.
EDIT: I found out what gives me the error.
public class GetUserInformations extends AsyncTask<String,Void,Void>{
Map<String,Object> tmpUser;
#Override
protected void onPreExecute(){
tmpUser = new HashMap<String,Object>();
}
#Override
protected Void doInBackground(String... arg) {
try{
int u_id = Integer.parseInt(arg[0]);
tmpUser = myDb.getUser(u_id); // downloading info
}catch(Exception e){
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void arg){
if ( tmpUser != null ){
Log.w("LOG",""+tmpUser.get("name"));
name = (String) tmpUser.get("name");
fbId = (String) tmpUser.get("id");
email = (String) tmpUser.get("email");
country = (Integer) tmpUser.get("country");
userName.setText(name);
profilepic.setProfileId(fbId);
userSubscribe.setVisibility(View.VISIBLE);
}
else {
Toast.makeText(getBaseContext(), "Error", Toast.LENGTH_SHORT).show();
finish();
}
}
}
When I open activity for first time, everything downloads fine, but when I backPress and click on link to this Activity again, then it gives me NullPointerException.
Do you know why ?
In your onItemClick function, try to put :
i = new Intent(getApplicationContext(), ShowProfile.class);
instead of :
i = new Intent(ShowPhotoDetails.this, ShowProfile.class);
remove this:
new GetUserInformations().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, id);
and use :
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
new GetUserInformations().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, id);
}
else {
new GetUserInformations().execute(id);
}
What is the API level on which you are facing this problem. Try to run it on different levels, taking Honeycomb as a reference.
Need to check the same and apply execute or executeONExecutor like this:
if (currentApiVersion >=
android.os.Build.VERSION_CODES.HONEYCOMB) {
new YourAsynctask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new YourAsynctask().execute();
}
Check this asynctask-threading-regression-confirmed blog post

ProgressDialog is not showing when .3gp file converting to a .zip

I am working on Android app.
I need to show a progress dialog box when I click on button.
In that button I am converting video file to .zip file and calculating that file size.
In this process I need to show a ProgressDialog, but it is not showing.
Screen get struck while calculating and after calculation it shows ProgressDialog and then screen navigating to the next screen.
My Code:
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MediaCheck.this.runOnUiThread(new Runnable() {
public void run() {
pd = ProgressDialog.show(MediaCheck.this, "",
"Checking the video compatability. Please wait", true);
}
});
video_Path= makeZip(video_Path);
if (video_Path.equalsIgnoreCase("File size is too large")) {
pd.dismiss();
Toast.makeText(getApplicationContext(),
"Large video", Toast.LENGTH_LONG)
.show();
return;
}
pd.dismiss();
// Doing screen navigation here.
}
});
Code to make a zip and know the size
private static String makeZip(String videoPath) {
byte[] buffer = new byte[1024];
String[] videoFileName = videoPath.split("/");
File directory = null;
try {
ContextWrapper cw = new ContextWrapper(context_this);
// path to /data/data/yourapp/app_data/imageDir
directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
FileOutputStream fos = new FileOutputStream(directory
+ "/IRCMS_Video.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze = null;
ze = new ZipEntry(videoFileName[5]);
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream(videoPath);
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
File videoZip = new File(directory + "/IRCMS_Video.zip");
videoLength = videoZip.length() / (1024 * 1024);
if (videoLength > 3)
return "File size is too large";
in.close();
zos.closeEntry();
// remember close it
zos.close();
System.out.println("Done");
} catch (IOException ex) {
ex.printStackTrace();
}
return directory.toString() + "/IRCMS_Video.zip";
}
}
Please help...
then you should try ASYNCTASK to easily perform your operation and reduce the complexity of using threads
private class Converter extends AsyncTask<String, Void, Void> { //Converter is class name
protected String doInBackground(String... urls) {
//THIS METHOD WILL BE CALLED AFTER ONPREEXECUTE
//YOUR NETWORK OPERATION HERE
return null;
}
protected void onPreExecute() {
super.onPreExecute();
//THIS METHOD WILL BE CALLED FIRST
//DO OPERATION LIKE SHOWING PROGRESS DIALOG PRIOR TO BEGIN NETWORK OPERATION
}
protected void onPostExecute(String result) {
super.onPostExecute();
//TNIS METHOD WILL BE CALLED AT LAST AFTER DOINBACKGROUND
//DO OPERATION LIKE UPDATING UI HERE
}
}
You are doing calculation on UI thread therfore it hangs your app. Do calculation on background thread. You can resolve this by-
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pd = ProgressDialog.show(MediaCheck.this, "",
"Checking the video compatability. Please wait", true);
Thread background = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
video_Path= makeZip(video_Path);
MediaCheck.this.runOnUiThread(new Runnable()
{
public void run()
{
if (video_Path.equalsIgnoreCase("File size is too large")) {
pd.dismiss();
Toast.makeText(getApplicationContext(),
"Large video", Toast.LENGTH_LONG)
.show();
pd.dismiss();
return;
}
}
});
}
});
background.start();
// Doing screen navigation here.
}
});

Android: Memory leak due to AsyncTask

I'm stuck with a memory leak that I cannot fix. I identified where it occurs, using the MemoryAnalizer but I vainly struggle to get rid of it. Here is the code:
public class MyActivity extends Activity implements SurfaceHolder.Callback {
...
Camera.PictureCallback mPictureCallbackJpeg = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera c) {
try {
// log the action
Log.e(getClass().getSimpleName(), "PICTURE CALLBACK JPEG: data.length = " + data);
// Show the ProgressDialog on this thread
pd = ProgressDialog.show(MyActivity.this, "", "Préparation", true, false);
// Start a new thread that will manage the capture
new ManageCaptureTask().execute(data, c);
}
catch(Exception e){
AlertDialog.Builder dialog = new AlertDialog.Builder(MyActivity.this);
...
dialog.create().show();
}
}
class ManageCaptureTask extends AsyncTask<Object, Void, Boolean> {
protected Boolean doInBackground(Object... args) {
Boolean isSuccess = false;
// initialize the bitmap before the capture
((myApp) getApplication()).setBitmapX(null);
try{
// Check if it is a real device or an emulator
TelephonyManager telmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String deviceID = telmgr.getDeviceId();
boolean isEmulator = "000000000000000".equalsIgnoreCase(deviceID);
// get the bitmap
if (isEmulator) {
((myApp) getApplication()).setBitmapX(BitmapFactory.decodeFile(imageFileName));
} else {
((myApp) getApplication()).setBitmapX(BitmapFactory.decodeByteArray((byte[]) args[0], 0, ((byte[])args[0]).length));
}
((myApp) getApplication()).setImageForDB(ImageTools.resizeBmp(((myApp) getApplication()).getBmp()));
// convert the bitmap into a grayscale image and display it in the preview
((myApp) getApplication()).setImage(makeGrayScale());
isSuccess = true;
}
catch (Exception connEx){
errorMessageFromBkgndThread = getString(R.string.errcapture);
}
return isSuccess;
}
protected void onPostExecute(Boolean result) {
// Pass the result data back to the main activity
if (MyActivity.this.pd != null) {
MyActivity.this.pd.dismiss();
}
if (result){
((ImageView) findViewById(R.id.apercu)).setImageBitmap(((myApp) getApplication()).getBmp());
((myApp) getApplication()).setBitmapX(null);
}
else{
// there was an error
ErrAlert();
}
}
}
};
private void ErrAlert(){
// notify the user about the error
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
...
dialog.create().show();
}
}
The activity is terminated on a button click, like this:
Button use = (Button) findViewById(R.id.use);
use.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MyActivity.this, NextActivity.class);
intent.putExtra("dbID", "-1");
intent.putExtra("category", category);
((myApp) getApplication()).setBitmapX(null);
MyActivity.this.startActivity(intent);
MyActivity.this.finish();
}
});
MemoryAnalyzer indicated the memory leak at:
((myApp) getApplication()).setBitmapX(BitmapFactory.decodeByteArray((byte[]) args[0], 0, ((byte[])args[0]).length));
I am grateful for any suggestion, thank you in advance.
Is your thread garbage collected after onPostExecute is called or is it still in the memory?
A Async Task will not be canceled or destroyed at the moment the activity is dismissed. If your thread is more or less lightweight and finishes after a small time, just keep it running and add a MyActivity.this.isFinishing() clause in the onPostExecute() method.
Your Task stores a implicit reference to your Activity MyActivity.this because it is a private class inside the activity. This means that your Activity will not be garbage collected until the task exits.
You can try below code snippet
protected void onPostExecute(Boolean result) {
if(YourActivity.this.isFinished()){
//to smomething here
}
}

Categories

Resources