Out of Memory on Samsung Galaxy devices - java

I've really tried my best, but I just can't find a fix for this Problem.
I wrote a Soundboard for Android devices, where every sound as well as its button images is loaded dynamically.
Here is the crucial paragraph in my code:
private void loadButtonColors(){
int rescount = AppConfig.BUTTONBACKGROUNDSRES(getApplicationContext()).size();
SharedPreferences prefs = getSharedPreferences("buttoncolors", 0);
String colors = null;
colors = prefs.getString("colors", null);
List<String> tempList = new ArrayList<String>();
if(colors != null){
tempList.addAll(Arrays.asList(TextUtils.split(colors, "~")));
}
if(colors == null || tempList.size() != MainActivity.SOUNDBUTTONS.size()){
for(#SuppressWarnings("unused") SoundButton s : MainActivity.SOUNDBUTTONS){
int randomint = new Random().nextInt(rescount);
Integer randominteger = Integer.valueOf(randomint);
String randomstring = String.valueOf(randominteger);
tempList.add(randomstring);
}
prefs.edit().putString("colors", TextUtils.join("~", tempList)).commit();
}
MainActivity.BUTTONCOLORS = (ArrayList<String>) tempList;
}
Later the button's images will be displayed with the images out of the following Arrays where the error seems to arise.
public static ArrayList<Drawable> BUTTONBACKGROUNDSRES(Context context){
ArrayList<Drawable> tempList = new ArrayList<Drawable>();
tempList.add(context.getResources().getDrawable(R.color.button_lblue));
tempList.add(context.getResources().getDrawable(R.color.button_lime));
tempList.add(context.getResources().getDrawable(R.color.button_orange));
tempList.add(context.getResources().getDrawable(R.color.button_pink));
tempList.add(context.getResources().getDrawable(R.color.button_red));
tempList.add(context.getResources().getDrawable(R.color.button_yellow));
return tempList;
};
The resulting error looks like this:
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:587)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:422)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:840)
at android.content.res.Resources.loadDrawable(Resources.java:2150)
at android.content.res.Resources.getDrawable(Resources.java:715)
at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:176)
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:937)
at android.graphics.drawable.Drawable.createFromXml(Drawable.java:877)
at android.content.res.Resources.loadDrawable(Resources.java:2132)
at android.content.res.Resources.getDrawable(Resources.java:715)
at com.centivo.inscope21soundboard.AppConfig.BUTTONBACKGROUNDSRES(AppConfig.java:45)
at com.centivo.inscope21soundboard.LauncherActivity.loadButtonColors(LauncherActivity.java:128)
at com.centivo.inscope21soundboard.LauncherActivity.access$1(LauncherActivity.java:127)
at com.centivo.inscope21soundboard.LauncherActivity$1.run(LauncherActivity.java:43)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5105)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
at dalvik.system.NativeStart.main(Native Method)
If you wanna check out the App visit the Playstore
EDIT: The size of every button image is about 70kb.

If you are running out of memory, store the tempList in BUTTONBACKGROUNDSRES in a member or static variable. It looks like every time you call BUTTONBACKGROUNDSRES, you are going to load a new set of Drawables. If these are always the same, there is no sense in loading them frequently from scratch and then leaving the tempList to be garbage collected. Just create the list once, then refer it.

Related

Application crash when delete digits (redmarobot input mask)

I am using redmadrobot:inputmask to use card number input mask. Input mask is working properly, but when I try to delete digits from my input, the application crashes.
Here is my code.
ArrayList<String> affineFormats = new ArrayList<>();
affineFormats.add("[0000] [000] [000] [000]");
affineFormats.add("[0000] [000000] [00000]");
affineFormats.add("[0000] [0000] [0000] [0000]");
String format = "[0000] [000] [000] [000]";
MaskedTextChangedListener listener = new MaskedTextChangedListener(
format,
affineFormats,
AffinityCalculationStrategy.CAPACITY,
true,
etCardNumber,
null,
new MaskedTextChangedListener.ValueListener() {
#Override
public void onTextChanged(boolean b, String s, String s1) {
//here some code
}
});
etCardNumber.addTextChangedListener(listener);
Error Log:
java.lang.IndexOutOfBoundsException: setSpan (21 ... 21) ends beyond length 20
at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1108)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:680)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:673)
at android.text.Selection.setSelection(Selection.java:76)
at android.text.Selection.setSelection(Selection.java:87)
at android.widget.EditText.setSelection(EditText.java:104)
at com.redmadrobot.inputmask.MaskedTextChangedListener.afterTextChanged(MaskedTextChangedListener.kt:192)
at android.widget.TextView.sendAfterTextChanged(TextView.java:8366)
at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:10557)
at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1061)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:573)
at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:233)
at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:229)
at android.view.inputmethod.BaseInputConnection.deleteSurroundingText(BaseInputConnection.java:252)
at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:389)
at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:78)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5763)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
Please help me resolve this issue.
Make sure you defined
<EditText
...
android:digits="0123456789 "
...
/>
for you input field, including space, as allowed symbol, because it is allowed in your mask.
You can do the same programmatically
editText.setInputType(InputType.TYPE_CLASS_NUMBER);
editText.setKeyListener(DigitsKeyListener.getInstance("0123456789 "));
Worked for me.

Getting the cover image of song from local media

ContentResolver musicResolver = getContentResolver();
Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri,null,null,null,null);
if(musicCursor!=null && musicCursor.moveToFirst()){
int idColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media._ID);
int titleColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
int artistColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
int imageColumn = musicCursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);
//Add songs to the array list
do{
String theArt = musicCursor.getString(imageColumn);
Bitmap image = BitmapFactory.decodeFile(theArt);
long songId = musicCursor.getLong(idColumn);
String songTitle = musicCursor.getString(titleColumn);
String songArtist = musicCursor.getString(artistColumn);
songsArrayList.add(new Songs(songId,songTitle,songArtist,image));
}while (musicCursor.moveToNext())
I want to get the cover image of the song which i am getting from the local storage, I have no idea how to do it so i get
int imageColumn =
musicCursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);
this code on internet to get album art this is showing error when i get string from it . That accessing column -1 , I think its not getting the right column to get the image , please let me know how to get the image from media in the way of above code
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.downloadbro.mumusic, PID: 10877
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.downloadbro.mumusic/com.downloadbro.mumusic.MainActivity}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2755)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2816)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1555)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6383)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:438)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at android.database.CursorWrapper.getString(CursorWrapper.java:137)
at com.downloadbro.mumusic.MainActivity.getSongList(MainActivity.java:80)
at com.downloadbro.mumusic.MainActivity.onCreate(MainActivity.java:45)
at android.app.Activity.performCreate(Activity.java:6861)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
And this may give me album art but i want media art no function as such showing to me

Cannot parse a String into Float in my app [duplicate]

This question already has an answer here:
java.lang.NumberFormatException: Invalid float: "x" in android
(1 answer)
Closed 5 years ago.
At first I am new in android development. I tried to make this small app where I wanted to take inputs from the users and show them to a (default)list view. When I put values in all the fields it works fine except when I keep the CGPA field empty it stopped. Unfortunately, MyApp is stopped
Here is the OnClickListener login button.
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setData();
}
});
Here is the lines of setData() method where i guess the problem has occurred.
My question is "Is it a right approach to parse data?"
Float cgpa = Float.parseFloat(editTextCgpa.getText().toString());
if(cgpa<=4.00 && cgpa > 0.00 ){
student.setCgpa(cgpa);
}
else{
error = true;
editTextCgpa.setError("CGPA must be within 4 in scale");
}
Android Monitor:
Here is the error message that i found in android monitor.
11-25 13:06:18.917 7896-7896/com.ariful.lict.lictpractice E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NumberFormatException: Invalid float: ""
at java.lang.StringToReal.invalidReal(StringToReal.java:63)
at java.lang.StringToReal.parseFloat(StringToReal.java:289)
at java.lang.Float.parseFloat(Float.java:300)
at com.ariful.lict.lictpractice.MainActivity.setData(MainActivity.java:55)
at com.ariful.lict.lictpractice.MainActivity$1.onClick(MainActivity.java:45)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
here does the convertion of the String to Float is causing the error ??
Is there anyone who can help me?
You are passing an empty string to be parsed...
Just change your code to check for null/empty String.
if(!editTextCgpa.getText().toString().isEmpty()){
Float cgpa = Float.parseFloat(editTextCgpa.getText().toString());
if(cgpa<=4.00 && cgpa > 0.00 ){
student.setCgpa(cgpa);
}
else{
error = true;
editTextCgpa.setError("CGPA must be within 4 in scale");
}
}

How to use a Cursor?

I have an app that receives the id of an animal and pass that id to a method from the database that will be read several times in a do-while. I want to know why this error happens?
This is my code:
bd = new BaseDados(getApplicationContext());
Cursor cc = bd.getIdAnimal(chipnumber);
if (cc.moveToFirst()) {
idanimal = cc.getInt(cc.getColumnIndex("idanimal"));
}
Cursor ccc = bd.getGruupsnosAnimals(idanimal);
do{
if(ccc.moveToFirst()){
String groupname= ccc.getString(ccc.getColumnIndex("groupname"));
}
}while (ccc.moveToNext());
This is my error:
Process: com.example.nobre.myapplication, PID: 4529
android.database.sqlite.SQLiteException: not an error (code 0)
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:845)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:144)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237)
at com.example.nobre.myapplication.Activities.VerAnimaisActivity.showDialog(VerAnimaisActivity.java:193)
at com.example.nobre.myapplication.Activities.VerAnimaisActivity$2.onClick(VerAnimaisActivity.java:153)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Exception: not an error? That's a new one.
Your bottom loop is a bit weird and may be a bug- you're moving to next but may not even have moved to first if that failed. And if it succeeded you'll infinitely loop. Try this instead:
if(ccc.moveToFirst()){
do{
String groupname= ccc.getString(ccc.getColumnIndex("groupname"));
}while (ccc.moveToNext());
}
do{
if(ccc.moveToFirst()){
String groupname= ccc.getString(ccc.getColumnIndex("groupname"));
}
}while (ccc.moveToNext());
this is an infinite loop, while you have next item in your cursor, you move to first one, and next iteration you would again move to first one.
Also do not forget to call Cursor.close() after usage.
Try this:
// Move the cursor to the first row if cursor is not empty
if(ccc.moveToFirst()) {
do{
String groupname= ccc.getString(ccc.getColumnIndex("groupname"));
}while (ccc.moveToNext()); // Move cursor to next row until it pass last entry
}
Instead of:
do{
if(ccc.moveToFirst()) {
String groupname= ccc.getString(ccc.getColumnIndex("groupname"));
}
}while (ccc.moveToNext());

Android Studio app keeps crashing after button click

Im a beginner in java but I'm trying to build exercises and I ran into this problem. The user types in a donation, presses the button and the value of donations increments. Ive written the entire code but when I click the button to add to the donation count, the app crashes. Ive followed all the teachings of my teacher. I create a method in the activity, the in the ui builder I go to the button on click property and set it to that method. It should go smoothly but it crashes whenever I click the button. This is my activity which I set the onClick property to computeDonation.
public void computeDonation(View v){
String addedText = ((EditText)findViewById(R.id.AmountText)).getText().toString();
DonationModel donation = new DonationModel(addedText);
String answer = donation.calcDonation();
((TextView)findViewById(R.id.totalText)).setText(answer);
}
This is the model:
String textAdded;
double addedDonation;
public DonationModel(String y) {
textAdded = y;
}
public String calcDonation(){
double counter = Double.parseDouble(textAdded);
addedDonation += counter;
Locale locale = new Locale("en", "CA");
NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);
return fmt.format(addedDonation);
}
Ive even tried without the number format just to see if it sends back to the activity but it doesn't. BTW for my class I'm using an older version of android studio.
This is the logcat:
02-15 17:12:28.797 21619-21619/ca.roumani.donations E/AndroidRuntime: FATAL EXCEPTION: main
Process: ca.roumani.donations, PID: 21619
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:5197)
at android.view.View$PerformClick.run(View.java:20909)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5197) 
at android.view.View$PerformClick.run(View.java:20909) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:5942) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 
Caused by: java.lang.NumberFormatException: Invalid double: ""
at java.lang.StringToReal.invalidReal(StringToReal.java:63)
at java.lang.StringToReal.parseDouble(StringToReal.java:267)
at java.lang.Double.parseDouble(Double.java:301)
at ca.roumani.donations.DonationModel.calcDonation(DonationModel.java:20)
at ca.roumani.donations.DonationActivity.computeDonation(DonationActivity.java:24)
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
at android.view.View.performClick(View.java:5197) 
at android.view.View$PerformClick.run(View.java:20909) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:5942) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 
It seems like your textAdded is an empty String, which causes the NumberFormatException and crashes your app. What you can do to prevent this, is to check if your textAdded is not empty before parsing it:
public String calcDonation() {
if (TextUtils.isEmpty(textAdded)) {
//textAdded is empty, so just return an empty String
return "";
}
//We're sure that textAdded has a value, so we can try to parse it
double counter = Double.parseDouble(textAdded);
addedDonation += counter;
Locale locale = new Locale("en", "CA");
NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);
return fmt.format(addedDonation);
}
Or just prevent the method from being invoked before the user has entered a value in the EditText view:
public void computeDonation(View v){
String addedText = ((EditText)findViewById(R.id.AmountText)).getText().toString();
if (TextUtils.isEmpty(textAdded)) {
Toast.makeText(context, "Please enter a valid number", Toast.LENGTH_SHORT).show();
} else {
DonationModel donation = new DonationModel(addedText);
String answer = donation.calcDonation();
((TextView)findViewById(R.id.totalText)).setText(answer);
}
}
I don't see where double addedDonation; is initialized, you can't use += when the variable has no value.
The problem is that you attempt to parse an empty string as a double. You need to verify that the user entered valid data before doing any calculations. One way to help you do this is to separate the calculation from the String passing and formatting. I suggest that you modify calcDonation() so that it only handles numeric data. Another method can worry about converting numbers to and from Strings. This will allow you to validate user input and display an appropriate error message when necessary.

Categories

Resources