I have a method which converts an image into a round shape and sets it in an imageview. The method works properly in most of the cases, but misbehaves when images with certain resolutions are selected.
The method:
public void decodeImageFile(String imagePath, Matrix m){
// Will need to do DP to PX algorith herer
Bitmap bitmap = decodeSampleBitmapFromFile(imagePath, 1024, 1024);
//bitmap = Bitmap.createScaledBitmap(bitmap, 540, 960, true);
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Log.e("height", ""+h);
Log.e("width", ""+w);
//to prevent crashing the app as this is not a legal resolution
// if (h == 1920 && w == 2160) {
// bitmap = Bitmap.createScaledBitmap(bitmap, 540, 960, true);
// }
// logic to check whether the resulting image has a height or
// width greater than 0
if (bitmap.getWidth() > 0 && bitmap.getHeight() > 0) {
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
bitmap = ImageController.transferSquare(bitmap);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
byteArray = baos.toByteArray();
bitmap = ImageController.resizeToHighResolutionCircle(bitmap);
choosePhotoBtn.setBackgroundResource(R.drawable.add_detail_photo_opaq_xhdpi);
yourPhoto.setImageBitmap(Bitmap.createScaledBitmap(bitmap, yourPhoto.getWidth(), yourPhoto.getHeight(), false));
}
}
I have seen the crashes for the 1080x1920 and 1920x2160 resolutions. The logcat for 1080x1920 resolution:
12-02 13:26:57.255: D/dalvikvm(28494): GC_FOR_ALLOC freed 14357K, 28% free 37780K/52472K, paused 17ms, total 17ms
12-02 13:26:57.335: E/height(28494): 1080
12-02 13:26:57.335: E/width(28494): 1920
12-02 13:26:57.350: D/dalvikvm(28494): GC_FOR_ALLOC freed 93K, 21% free 41738K/52472K, paused 12ms, total 12ms
12-02 13:26:57.355: I/dalvikvm-heap(28494): Grow heap (frag case) to 46.646MB for 4147216-byte allocation
12-02 13:26:57.365: D/dalvikvm(28494): GC_FOR_ALLOC freed <1K, 19% free 45788K/56524K, paused 11ms, total 11ms
12-02 13:26:57.610: D/dalvikvm(28494): GC_FOR_ALLOC freed 9108K, 27% free 42971K/58508K, paused 14ms, total 14ms
12-02 13:26:57.635: D/dalvikvm(28494): GC_FOR_ALLOC freed 5156K, 22% free 43217K/54748K, paused 15ms, total 15ms
12-02 13:26:57.645: I/dalvikvm-heap(28494): Grow heap (frag case) to 48.585MB for 4665616-byte allocation
12-02 13:26:57.665: D/dalvikvm(28494): GC_FOR_ALLOC freed 0K, 20% free 47773K/59308K, paused 17ms, total 17ms
12-02 13:27:03.610: W/dalvikvm(29085): threadid=12: thread exiting with uncaught exception (group=0x41939c08)
12-02 13:27:03.610: E/AndroidRuntime(29085): FATAL EXCEPTION: Parse.initialize Disk Check & Starting Command Cache
12-02 13:27:03.610: E/AndroidRuntime(29085): Process: com.navitas.studystory, PID: 29085
12-02 13:27:03.610: E/AndroidRuntime(29085): java.lang.SecurityException: Unable to find app for caller android.app.ApplicationThreadProxy#43839f28 (pid=29085) when registering receiver android.content.IIntentReceiver$Stub$Proxy#42c70b60
12-02 13:27:03.610: E/AndroidRuntime(29085): at android.os.Parcel.readException(Parcel.java:1472)
12-02 13:27:03.610: E/AndroidRuntime(29085): at android.os.Parcel.readException(Parcel.java:1426)
12-02 13:27:03.610: E/AndroidRuntime(29085): at android.app.ActivityManagerProxy.registerReceiver(ActivityManagerNative.java:2551)
12-02 13:27:03.610: E/AndroidRuntime(29085): at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1821)
12-02 13:27:03.610: E/AndroidRuntime(29085): at android.app.ContextImpl.registerReceiver(ContextImpl.java:1789)
12-02 13:27:03.610: E/AndroidRuntime(29085): at android.app.ContextImpl.registerReceiver(ContextImpl.java:1783)
12-02 13:27:03.610: E/AndroidRuntime(29085): at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:479)
12-02 13:27:03.610: E/AndroidRuntime(29085): at com.parse.ConnectivityNotifier.tryToRegisterForNetworkStatusNotifications(ConnectivityNotifier.java:55)
12-02 13:27:03.610: E/AndroidRuntime(29085): at com.parse.ConnectivityNotifier.addListener(ConnectivityNotifier.java:34)
12-02 13:27:03.610: E/AndroidRuntime(29085): at com.parse.ParseCommandCache.<init>(ParseCommandCache.java:101)
12-02 13:27:03.610: E/AndroidRuntime(29085): at com.parse.Parse.getEventuallyQueue(Parse.java:527)
12-02 13:27:03.610: E/AndroidRuntime(29085): at com.parse.Parse$1.run(Parse.java:126)
12-02 13:27:03.680: W/ApplicationPackageManager(29098): getCSCPackageItemText()
12-02 13:27:03.780: D/dalvikvm(29098): GC_FOR_ALLOC freed 206K, 12% free 17072K/19260K, paused 18ms, total 19ms
12-02 13:27:03.795: I/dalvikvm-heap(29098): Grow heap (frag case) to 25.620MB for 7356976-byte allocation
12-02 13:27:03.815: D/dalvikvm(29098): GC_FOR_ALLOC freed 0K, 9% free 24257K/26448K, paused 17ms, total 17ms
12-02 13:27:03.845: E/Lifecycle(29098): The onCreate() event
12-02 13:27:03.845: E/Lifecycle(29098): The onStart() event
12-02 13:27:03.850: E/Lifecycle(29098): The onResume() event
12-02 13:27:03.940: D/OpenGLRenderer(29098): Enabling debug mode 0
12-02 13:27:33.950: E/Lifecycle(29098): The onPause() event
12-02 13:27:33.955: E/Lifecycle(29098): The onStop() event
Please tell me where I am going wrong? What is a miss?
Create Class
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
if(ex.getClass().equals(OutOfMemoryError.class))
{
try {
android.os.Debug.dumpHprofData("/sdcard/dump.hprof");
}
catch (IOException e) {
e.printStackTrace();
}
}
ex.printStackTrace();
}
}
and then put the following code in mainActivity
Thread.currentThread().setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
Add android:largeHeap="true" to your applicaton tag in the manifest to be able to claim more memory and use multi-threading for heavy operations like this. An asynctask, the built in thread class for short term operations, would be perfect, though your GUI will still hang for a bit while it is waiting for the task to complete decoding.
How to write ASyncTasks
For example, a decoder task.
public class BitmapDecoderTask extends AsyncTask<File, Integer, Bitmap> {
protected Bitmap doInBackground(File... files) {
int count = files.length;
Bitmap fullImage = null;
for (int i = 0; i < count; i++) {
fullImage = BitmapFactory.decodeFile(files[i].getAbsolutePath());
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return fullImage;
}
protected void onProgressUpdate(Integer... progress) {
//setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
//showDialog("Downloaded " + result + " bytes");
}
}
After which you can just create one of these tasks, call execute on it and get() the result or if it's a write action, just let it run and finish whenever.
Do remember to recycle() your bitmaps to avoid unnecessary memory claiming.
Related
My android app is supposed to read about 25kb from a InputStream which is wrapped in a BufferedReader. This happens in a background Thread that communicates via a Handler. But when starting to read the Thread seems to be blocked and a debug message shows up:
09-29 22:56:27.837 13625-13640/de.jzbor.epos I/art: Background sticky concurrent mark sweep GC freed 519353(7MB) AllocSpace objects, 0(0B) LOS objects, 77% free, 2MB/10MB, paused 797us total 109.196ms
I don't know how to handle or bypass it and I wasn't able to find something useful on the internet. I would be very thankful for any tipps or solutions.
Here is the code and the log:
Method:
#Override
public void run() {
if (request == null)
return;
int responseHash = 0;
int returnCode = 0;
String timestamp = "0";
int responseType = 0;
Object returnObject = "";
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if ((networkInfo == null) || (!networkInfo.isConnectedOrConnecting())) {
returnCode = 1;
} else {
try {
socket = new Socket(HOST, PORT);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pw.println("get " + request);
pw.flush();
String responseString = "";
Log.d("EpOs", "1");
while (!br.ready());
int i = 0;
while (br.ready()){
Log.d("EpOs", "ln"+i++);
char c;
c = (char)br.read();
if (c != 0)
responseString += Character.toString(c);
}
Log.d("EpOs", "1.5");
System.out.println(responseString);
timestamp = new SimpleDateFormat("E HH:mm").format(new Date());
switch (request) {
case "service/vertretungsplan": {
try {
responseType = 101;
SubstituteDay sd = SubstitutePlanGetter.getSubstitutions(responseString)[0];
} catch (URISyntaxException | ImplicitLoginException e) {
e.printStackTrace();
returnCode = 21;
}
break;
}
default: {
returnCode = 2;
}
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
returnCode = 3;
}
Log.d("EpOs", "2");
Integer rc = returnCode;
Object[] objects = new Object[3];
objects[0] = rc;
objects[1] = timestamp;
objects[2] = returnObject;
Message msg = handler.obtainMessage(responseType, objects);
msg.sendToTarget();
}
Logcat:
09-29 23:12:42.866 21779-21779/? I/art: Late-enabling -Xcheck:jni
09-29 23:12:43.278 21779-21779/de.jzbor.epos I/InstantRun: starting instant run server: is main process
09-29 23:12:43.476 21779-21779/de.jzbor.epos W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
09-29 23:12:43.533 21779-21779/de.jzbor.epos D/EpOs: Test
09-29 23:12:44.150 21779-21779/de.jzbor.epos I/ViewRootImpl: CPU Rendering VSync enable = false
09-29 23:12:44.153 21779-21804/de.jzbor.epos D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
09-29 23:12:44.215 21779-21804/de.jzbor.epos I/Adreno-EGL: <qeglDrvAPI_eglInitialize:379>: EGL 1.4 QUALCOMM build: ()
OpenGL ES Shader Compiler Version: E031.25.03.04
Build Date: 04/28/15 Tue
Local Branch:
Remote Branch:
Local Patches:
Reconstruct Branch:
09-29 23:12:44.217 21779-21804/de.jzbor.epos I/OpenGLRenderer: Initialized EGL, version 1.4
09-29 23:12:44.231 21779-21804/de.jzbor.epos D/OpenGLRenderer: Enabling debug mode 0
09-29 23:12:44.396 21779-21779/de.jzbor.epos W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
09-29 23:12:44.501 21779-21779/de.jzbor.epos I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy#69cc367 time:42529086
09-29 23:12:48.039 21779-21829/de.jzbor.epos D/EpOs: 1
09-29 23:12:56.169 21779-21794/de.jzbor.epos I/art: Background sticky concurrent mark sweep GC freed 569396(9MB) AllocSpace objects, 0(0B) LOS objects, 77% free, 2MB/10MB, paused 768us total 112.713ms
09-29 23:13:03.718 21779-21794/de.jzbor.epos I/art: Background partial concurrent mark sweep GC freed 523840(8MB) AllocSpace objects, 0(0B) LOS objects, 83% free, 2MB/14MB, paused 656us total 116.436ms
09-29 23:13:14.916 21779-21794/de.jzbor.epos I/art: Background sticky concurrent mark sweep GC freed 784615(11MB) AllocSpace objects, 0(0B) LOS objects, 77% free, 2MB/10MB, paused 489us total 122.385ms
09-29 23:13:29.955 21779-21794/de.jzbor.epos I/art: Background sticky concurrent mark sweep GC freed 521041(7MB) AllocSpace objects, 0(0B) LOS objects, 77% free, 2MB/10MB, paused 727us total 103.527ms
09-29 23:15:34.196 21779-22644/de.jzbor.epos D/EpOs: 1
09-29 23:16:24.117 21779-21794/de.jzbor.epos I/art: Background sticky concurrent mark sweep GC freed 514462(7MB) AllocSpace objects, 0(0B) LOS objects, 76% free, 2MB/10MB, paused 539us total 101.177ms
09-29 23:17:09.050 21779-21794/de.jzbor.epos I/art: Background sticky concurrent mark sweep GC freed 514702(7MB) AllocSpace objects, 0(0B) LOS objects, 75% free, 2MB/10MB, paused 607us total 106.134ms
My application when I click a buttons is freezing and in anroid monit I see :
03-22 13:01:33.490 25636-26150/com.smok.maps D/dalvikvm: GC_FOR_ALLOC freed 2468K, 11% free 29508K/32996K, paused 65ms, total 65ms
03-22 13:01:36.914 25636-26150/com.smok.maps D/dalvikvm: GC_FOR_ALLOC freed 3957K, 17% free 28675K/34324K, paused 54ms, total 54ms
03-22 13:01:37.744 25636-25636/com.smok.maps I/Choreographer: Skipped 271 frames! The application may be doing too much work on its main thread.
03-22 13:01:39.907 25636-26150/com.smok.maps D/dalvikvm: GC_FOR_ALLOC freed 3903K, 19% free 27910K/34324K, paused 42ms, total 42ms
This is an action what I do :
btUnselectAll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
// for (RowBean aRowBean_data : rowBeen) {
// aRowBean_data.setSelected(false);
// }
for (RowBean rowBean : Adapter.data) {
rowBean.setSelected(false);
}
adapter.notifyDataSetChanged();
for (ObjectDefExtends objectDefExtends : Singleton.getInstance().getListaODE()) {
objectDefExtends.visible = false;
editor.putInt(objectDefExtends.id.toString(), 0);
editor.apply();
}
}
});
i am developing a project where i compare two item images,So if two items will have same image after clicking these items it should be permanently delete from the GridView. my code is given below and this code encounter a problem. please any one help me.
MainActivity.java
public class MainActivity extends Activity {
Context ctx;
int imagesArray[];
GridViewContent adapter;
List<Integer> pictures, pictureList;
boolean flage = false;
int save1, save2;
int img1 = -1, img2 = -1;
public int OriginalArray[] = { R.drawable.sample_0, R.drawable.sample_1,
R.drawable.sample_2, R.drawable.sample_3, R.drawable.sample_0,
R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3 };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
shuffleArray();
final GridView grid = (GridView) findViewById(R.id.gv_memory);
grid.setAdapter(new GridViewContent(this));
}
private void shuffleArray() {
// TODO Auto-generated method stub
pictures = new ArrayList<Integer>();
for (int index = 0; index < OriginalArray.length; index++) {
pictures.add(OriginalArray[index]);
}
Collections.shuffle(pictures);
}
public class GridViewContent extends BaseAdapter {
private Context context;
private List<Integer> pictureList = new ArrayList<Integer>();
public GridViewContent(Context c) {
context = c;
for (int i = 0; i < 8; i++) {
pictureList.add(R.drawable.question);
}
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return (pictureList.size());
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return pictureList.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(final int position, final View arg1,
final ViewGroup arg2) {
// TODO Auto-generated method stub
final ImageView myimage = new ImageView(context);
myimage.setImageResource(pictureList.get(position));
// myimage.setImageResource(pictures.get(pictureArray[position]));
myimage.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
myimage.setLayoutParams(new GridView.LayoutParams(70, 70));
final GridView grid = (GridView) findViewById(R.id.gv_memory);
myimage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
myimage.setImageResource(pictures.get(position));
// View v1 = new View(context);
if (flage == false) {
img1 = pictures.get(position);
// v1 = arg2.getChildAt(position);
save1 = position;
flage = true;
} else if (flage == true) {
img2 = pictures.get(position);
save2 = position;
checkResult(save1, save2);
flage = false;
}
// else if(f)
}
});
return myimage;
}
}
public void checkResult(int s1, int s2) {
if (img1 == img2) {
pictureList.remove(s1); //this is line no 116
pictureList.remove(s1);
adapter.notifyDataSetChanged();
Toast.makeText(MainActivity.this, "Congratualatin !!!!",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this, "Sorry!!!!", Toast.LENGTH_LONG)
.show();
final GridView grid = (GridView) findViewById(R.id.gv_memory);
grid.setAdapter(new GridViewContent(this));
}
}
}
LogCat.
03-14 01:07:12.791: D/dalvikvm(1598): GC_FOR_ALLOC freed 38K, 7% free 2771K/2980K, paused 183ms, total 185ms
03-14 01:07:12.811: I/dalvikvm-heap(1598): Grow heap (frag case) to 3.943MB for 1127536-byte allocation
03-14 01:07:12.941: D/dalvikvm(1598): GC_FOR_ALLOC freed 2K, 6% free 3870K/4084K, paused 128ms, total 128ms
03-14 01:07:13.111: D/dalvikvm(1598): GC_FOR_ALLOC freed 4K, 5% free 4253K/4448K, paused 25ms, total 26ms
03-14 01:07:13.143: I/dalvikvm-heap(1598): Grow heap (frag case) to 5.688MB for 1440016-byte allocation
03-14 01:07:13.271: D/dalvikvm(1598): GC_FOR_ALLOC freed <1K, 4% free 5659K/5856K, paused 127ms, total 127ms
03-14 01:07:13.481: I/Choreographer(1598): Skipped 49 frames! The application may be doing too much work on its main thread.
03-14 01:07:13.571: D/gralloc_goldfish(1598): Emulator without GPU emulation detected.
03-14 01:08:36.011: D/dalvikvm(1598): GC_FOR_ALLOC freed 357K, 9% free 5587K/6116K, paused 34ms, total 35ms
03-14 01:08:36.021: I/dalvikvm-heap(1598): Grow heap (frag case) to 6.543MB for 971296-byte allocation
03-14 01:08:36.154: D/dalvikvm(1598): GC_FOR_ALLOC freed 1K, 8% free 6534K/7068K, paused 123ms, total 123ms
03-14 01:08:39.422: D/dalvikvm(1598): GC_FOR_ALLOC freed 2385K, 8% free 5419K/5876K, paused 76ms, total 78ms
03-14 01:08:39.492: D/dalvikvm(1598): GC_FOR_ALLOC freed 1K, 4% free 5654K/5876K, paused 40ms, total 41ms
03-14 01:08:41.352: D/AndroidRuntime(1598): Shutting down VM
03-14 01:08:41.352: W/dalvikvm(1598): threadid=1: thread exiting with uncaught exception (group=0x41465700)
03-14 01:08:41.532: E/AndroidRuntime(1598): FATAL EXCEPTION: main
03-14 01:08:41.532: E/AndroidRuntime(1598): java.lang.NullPointerException
03-14 01:08:41.532: E/AndroidRuntime(1598): at com.example.memoryforkids.MainActivity.checkResult(MainActivity.java:116)
03-14 01:08:41.532: E/AndroidRuntime(1598): at com.example.memoryforkids.MainActivity$GridViewContent$1.onClick(MainActivity.java:102)
03-14 01:08:41.532: E/AndroidRuntime(1598): at android.view.View.performClick(View.java:4240)
03-14 01:08:41.532: E/AndroidRuntime(1598): at android.view.View$PerformClick.run(View.java:17721)
03-14 01:08:41.532: E/AndroidRuntime(1598): at android.os.Handler.handleCallback(Handler.java:730)
03-14 01:08:41.532: E/AndroidRuntime(1598): at android.os.Handler.dispatchMessage(Handler.java:92)
03-14 01:08:41.532: E/AndroidRuntime(1598): at android.os.Looper.loop(Looper.java:137)
03-14 01:08:41.532: E/AndroidRuntime(1598): at android.app.ActivityThread.main(ActivityThread.java:5103)
03-14 01:08:41.532: E/AndroidRuntime(1598): at java.lang.reflect.Method.invokeNative(Native Method)
03-14 01:08:41.532: E/AndroidRuntime(1598): at java.lang.reflect.Method.invoke(Method.java:525)
03-14 01:08:41.532: E/AndroidRuntime(1598): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
03-14 01:08:41.532: E/AndroidRuntime(1598): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-14 01:08:41.532: E/AndroidRuntime(1598): at dalvik.system.NativeStart.main(Native Method)
main.xml
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gv_memory"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="90dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp" >
</GridView>
Thanks in advance..
Ok so, I found the bug, you have defined the pictureList variable in two places, the one being initialized inside the adapter class is a local variable. When checkResult is called, it uses the pictureList variable belonging to the main activity class. Do the following:
1) Remove the local variable inside the adapter class.
2) Initialize the pictureList variable that has been defined in the activity class.
This fixes the error. Its working fine on my machine now!
Also, there are a lot of issues with the logic you are using, you will realize that once you fix this error.
I've started to do a speedtest application recently.
The method is simple :
I instanciate multiple threads all downloading the same uncompressible file, then i calculate the average download speed.
But I've got some performances problems I think. When i start the test with more than one thread, i see a lot of GC_CONCURRENT freed and WAIT_FOR_CONCURRENT_GC in the logCat.
I don't understand where's that comming from.
Habitually these problems seems to appear in certain circumpstances, like instanciating too much objects, or huge objects, but i don't think it's the case here...
Here is my code (simplified - without speed calculation):
public class SpeedTest extends Activity{
private final int NB_THREADS = 2;
private long bytesIn;
private long downloadTime;
private List<Downloader> downloaders = new ArrayList<Downloader>();
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.speed_test);
bytesIn = 0;
for (int i = 0; i < NB_THREADS; i++){
downloaders.add(new Downloader());
downloaders.get(i).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, i);
}
}
private synchronized void addBytes(){ bytesIn++; }
private class Downloader extends AsyncTask<Integer, Void, Void>{
#Override
protected Void doInBackground(Integer... params){
Log.d("eduine", "Downloader " + params[0] + " started");
try{
InputStream stream = new URL("http://test-de-vitesse.ariase.com/ariasetool/1mb_random.bin").openConnection().getInputStream();
while((stream.skip(1)) != 0){
addBytes();
}
stream.close();
}catch (MalformedURLException e){
e.printStackTrace();
Log.e("eduine", "malformed url : " + e.getMessage());
}catch (IOException e){
e.printStackTrace();
Log.e("eduine", "io error : " + e.getMessage());
}
Log.d("eduine", "Downloader " + params[0] + " terminated");
return null;
}
}
}
So I'd like to know if someone already experienced this problem, or have any idea why is there these performances problems, because it distorts the speed calculations.
Thanks in advance!
EDIT : forgot to post the logCat, sorry.
02-12 14:18:40.945: D/eduine(15637): Downloader 0 started
02-12 14:18:40.955: D/eduine(15637): Downloader 1 started
02-12 14:18:41.355: D/dalvikvm(15637): GC_CONCURRENT freed 3102K, 33% free 7552K/11240K, paused 3ms+3ms, total 20ms
02-12 14:18:41.395: D/dalvikvm(15637): GC_CONCURRENT freed 1564K, 33% free 7533K/11240K, paused 3ms+3ms, total 18ms
02-12 14:18:41.465: D/dalvikvm(15637): GC_CONCURRENT freed 1657K, 33% free 7537K/11240K, paused 2ms+7ms, total 20ms
02-12 14:18:41.465: D/dalvikvm(15637): WAIT_FOR_CONCURRENT_GC blocked 8ms
02-12 14:18:41.485: D/dalvikvm(15637): GC_CONCURRENT freed 1657K, 33% free 7541K/11240K, paused 2ms+3ms, total 17ms
02-12 14:18:41.485: D/dalvikvm(15637): WAIT_FOR_CONCURRENT_GC blocked 10ms
02-12 14:18:41.505: D/dalvikvm(15637): GC_CONCURRENT freed 1669K, 33% free 7533K/11240K, paused 3ms+1ms, total 17ms
02-12 14:18:41.505: D/dalvikvm(15637): WAIT_FOR_CONCURRENT_GC blocked 10ms
02-12 14:18:41.525: D/dalvikvm(15637): GC_CONCURRENT freed 1609K, 33% free 7537K/11240K, paused 3ms+3ms, total 16ms
02-12 14:18:41.545: D/dalvikvm(15637): GC_CONCURRENT freed 1669K, 34% free 7529K/11240K, paused 3ms+2ms, total 16ms
02-12 14:18:41.545: D/dalvikvm(15637): WAIT_FOR_CONCURRENT_GC blocked 13ms
etc etc... until
02-12 14:21:14.795: D/dalvikvm(16164): GC_CONCURRENT freed 1537K, 33% free 7533K/11240K, paused 3ms+2ms, total 16ms
02-12 14:21:14.815: D/dalvikvm(16164): GC_CONCURRENT freed 1537K, 33% free 7533K/11240K, paused 2ms+2ms, total 15ms
02-12 14:21:14.835: D/dalvikvm(16164): GC_CONCURRENT freed 1537K, 33% free 7533K/11240K, paused 2ms+3ms, total 16ms
02-12 14:21:14.845: D/eduine(16164): Downloader 0 terminated at 1392211274859
02-12 14:21:14.855: D/dalvikvm(16164): GC_CONCURRENT freed 1545K, 34% free 7529K/11240K, paused 3ms+3ms, total 17ms
02-12 14:21:14.915: D/eduine(16164): Downloader 1 terminated at 1392211274925
EDIT : same problem using ThreadPool, code below.
public class SpeedTest extends Activity{
private final int NB_OF_THREADS = 8;
private long bytesIn;
private long start;
ExecutorService executorService = new ThreadPoolExecutor(NB_OF_THREADS, NB_OF_THREADS, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(NB_OF_THREADS, true), new ThreadPoolExecutor.CallerRunsPolicy());
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.speed_test);
bytesIn = 0;
start = System.currentTimeMillis();
for (int i = 0; i < NB_OF_THREADS; i++) executorService.submit(new Downloader(i));
}
private synchronized void addByte(){ bytesIn++; }
private class Downloader implements Runnable{
private int id;
private InputStream stream;
private long downloadTime;
public Downloader(int _id){ id = _id; }
#Override
public void run(){
Log.d("eduine", "Downloader " + id + " started at " + System.currentTimeMillis());
try{
HttpURLConnection connexion = (HttpURLConnection) new URL("http://test-de-vitesse.ariase.com/ariasetool/1mb_random.bin").openConnection();
connexion.setUseCaches(false);
stream = connexion.getInputStream();
while((stream.skip(1)) != 0) addByte();
stream.close();
downloadTime = (System.currentTimeMillis() - start);
downloadTime = downloadTime == 0 ? 1 : downloadTime;
}catch (MalformedURLException e){
e.printStackTrace();
Log.e("eduine", "malformed url : " + e.getMessage());
}catch (IOException e){
e.printStackTrace();
Log.e("eduine", "io error : " + e.getMessage());
}
Log.d("eduine", "Downloader " + id + " terminated at " + System.currentTimeMillis());
}
}
}
Thread objects themselves consume much memory for their stacks. To clean your test from instantiate/free threads, do not use AsyncTask (which creates Thread), but create a fixed threadpool beforehand, start test, wait it to end, and only then shutdown the thread pool.
everytime I run this code I get a force close, which i don't understand. Im new to Android development, can anybody help? I'm really thankful for any tips from you guys. So far i just understood, that the memory space is running out, but how can I prevent the memory from running low?
My code:
Boolean start = true;
HttpPost httppost;
StringBuffer buffer;
HttpResponse response;
HttpClient httpclient;
List<NameValuePair> nameValuePair;
TextView txtEntries;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
txtEntries = (TextView)findViewById(R.id.txtEntries);
SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String User = p.getString("User", "");
String Password = p.getString("Password", "");
txtEntries.setText("user:" + User + "Passwort:" + Password);
getEntries.start();
start = true;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main_screen, menu);
return true;
}
Thread getEntries = new Thread() {
public void run() {
//while(!login_thread.isInterrupted()) {
while (getEntries.isInterrupted() == false) {
try {
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (start) {
//Code for login+Action from saved text
SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String User = p.getString("User", "");
String Password = p.getString("Password", "");
login("Entries", User, Password);
}
}
//while (start == true){
//login(box_User.getText().toString(), box_Password.getText().toString());
//}
//}
}
};
//implement Handler
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
getEntries.interrupt();
txtEntries = (TextView)findViewById(R.id.txtEntries);
txtEntries.setText("Handler");
Bundle bundle = msg.getData();
Boolean Connection = bundle.getBoolean("Connection");
String response = bundle.getString("Entries");
if (Connection) {
// Toast.makeText(getBaseContext(), "Connection", 5000).show();
if (response != "") {
//Code which shows all entries
Toast.makeText(getBaseContext(), "Response", 5000).show();
txtEntries.setText(response);
} else {
txtEntries.setText("Empty");
}
}else {
txtEntries.setText("No connection");
getEntries.interrupt();
}
}
};
// getData method
private void login(String Action, String User, String Password) {
// TODO Auto-generated method stub
start = false;
Message msg = handler.obtainMessage();
Bundle bundle = new Bundle();
httppost = new HttpPost("http://10.0.2.2/KHG/api/check-login.php");
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 15000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 15000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
httpclient = new DefaultHttpClient(httpParameters);
nameValuePair = new ArrayList<NameValuePair>(1);
nameValuePair.add(new BasicNameValuePair("User", User));
nameValuePair.add(new BasicNameValuePair("Password", Password));
nameValuePair.add(new BasicNameValuePair("Action", Action));
try {
httppost.setEntity(new UrlEncodedFormEntity(nameValuePair));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
e.printStackTrace();
bundle.putBoolean("Connection", false);
bundle.putString("Entries", "");
msg.setData(bundle);
handler.sendMessage(msg);
}
try {
response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
bundle.putBoolean("Connection", false);
bundle.putString("Entries", "");
msg.setData(bundle);
handler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
bundle.putBoolean("Connection", false);
bundle.putString("Entries", "");
msg.setData(bundle);
handler.sendMessage(msg);
}
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String response;
try {
// Toast.makeText(getBaseContext(), "test", Toast.LENGTH_LONG).show();
response = httpclient.execute(httppost, responseHandler);
SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
p.edit().putString("Data", response).commit();
bundle.putBoolean("Connection", true);
bundle.putString("Entries", "ok");
msg.setData(bundle);
handler.sendMessage(msg);
}
catch (Exception e) {
e.printStackTrace();
bundle.putBoolean("Connection", false);
bundle.putString("Entries", "");
msg.setData(bundle);
handler.sendMessage(msg);
// Toast.makeText(getBaseContext(), "exception", Toast.LENGTH_LONG).show();
}
}
}
And my log:
03-23 16:32:22.683: D/dalvikvm(741): GC_FOR_ALLOC freed 135K, 4% free 8821K/9159K, paused 60ms
03-23 16:32:22.822: W/SingleClientConnManager(741): Invalid use of SingleClientConnManager: connection still allocated.
03-23 16:32:22.822: W/SingleClientConnManager(741): Make sure to release the connection before allocating another one.
03-23 16:32:23.012: W/System.err(741): java.lang.InterruptedException
03-23 16:32:23.012: W/System.err(741): at java.lang.VMThread.sleep(Native Method)
03-23 16:32:23.012: W/System.err(741): at java.lang.Thread.sleep(Thread.java:1214)
03-23 16:32:23.022: W/System.err(741): at java.lang.Thread.sleep(Thread.java:1196)
03-23 16:32:23.022: W/System.err(741): at com.shr.khg.MainActivity$2.run(MainActivity.java:109)
03-23 16:32:25.342: D/dalvikvm(741): GC_FOR_ALLOC freed 80K, 3% free 9148K/9415K, paused 60ms
03-23 16:32:25.442: W/SingleClientConnManager(741): Invalid use of SingleClientConnManager: connection still allocated.
03-23 16:32:25.442: W/SingleClientConnManager(741): Make sure to release the connection before allocating another one.
03-23 16:32:25.822: D/dalvikvm(741): GC_CONCURRENT freed 40K, 3% free 9558K/9799K, paused 21ms+9ms
03-23 16:32:25.942: D/dalvikvm(741): GC_FOR_ALLOC freed 123K, 5% free 9629K/10119K, paused 68ms
03-23 16:32:25.952: I/dalvikvm-heap(741): Grow heap (frag case) to 9.770MB for 262160-byte allocation
03-23 16:32:26.092: D/dalvikvm(741): GC_FOR_ALLOC freed 0K, 6% free 9885K/10439K, paused 69ms
03-23 16:32:26.262: D/dalvikvm(741): GC_FOR_ALLOC freed 132K, 7% free 9757K/10439K, paused 55ms
03-23 16:32:26.262: I/dalvikvm-heap(741): Grow heap (frag case) to 10.145MB for 524304-byte allocation
03-23 16:32:26.412: D/dalvikvm(741): GC_FOR_ALLOC freed 0K, 7% free 10269K/11015K, paused 57ms
03-23 16:32:26.682: D/dalvikvm(741): GC_CONCURRENT freed 262K, 10% free 10014K/11015K, paused 13ms+3ms
03-23 16:32:26.852: D/dalvikvm(741): GC_FOR_ALLOC freed 1K, 10% free 10013K/11015K, paused 71ms
03-23 16:32:26.872: I/dalvikvm-heap(741): Grow heap (frag case) to 10.895MB for 1048592-byte allocation
03-23 16:32:27.042: D/dalvikvm(741): GC_FOR_ALLOC freed 0K, 9% free 11037K/12103K, paused 63ms
03-23 16:32:27.302: D/dalvikvm(741): GC_CONCURRENT freed 518K, 14% free 10526K/12103K, paused 26ms+5ms
03-23 16:32:28.212: D/dalvikvm(741): GC_FOR_ALLOC freed 9K, 14% free 10525K/12103K, paused 102ms
03-23 16:32:28.242: I/dalvikvm-heap(741): Grow heap (frag case) to 12.395MB for 2097168-byte allocation
03-23 16:32:28.562: D/dalvikvm(741): GC_FOR_ALLOC freed 0K, 12% free 12573K/14215K, paused 89ms
03-23 16:32:28.912: D/dalvikvm(741): GC_CONCURRENT freed 1030K, 19% free 11550K/14215K, paused 18ms+23ms
03-23 16:32:31.352: D/dalvikvm(741): GC_FOR_ALLOC freed 26K, 19% free 11549K/14215K, paused 79ms
03-23 16:32:31.412: I/dalvikvm-heap(741): Grow heap (frag case) to 15.395MB for 4194320-byte allocation
03-23 16:32:31.723: D/dalvikvm(741): GC_FOR_ALLOC freed 0K, 15% free 15645K/18375K, paused 87ms
03-23 16:32:31.932: D/dalvikvm(741): GC_CONCURRENT freed 2054K, 27% free 13598K/18375K, paused 19ms+4ms
03-23 16:32:38.491: D/dalvikvm(741): GC_FOR_ALLOC freed 59K, 27% free 13597K/18375K, paused 67ms
03-23 16:32:38.621: I/dalvikvm-heap(741): Grow heap (frag case) to 21.395MB for 8388624-byte allocation
03-23 16:32:39.031: D/dalvikvm(741): GC_FOR_ALLOC freed 0K, 19% free 21789K/26631K, paused 98ms
03-23 16:32:39.341: D/dalvikvm(741): GC_CONCURRENT freed 4101K, 34% free 17694K/26631K, paused 17ms+11ms
03-23 16:32:52.093: D/dalvikvm(741): GC_FOR_ALLOC freed 124K, 34% free 17693K/26631K, paused 79ms
03-23 16:32:52.093: I/dalvikvm-heap(741): Forcing collection of SoftReferences for 16777232-byte allocation
03-23 16:32:52.242: D/dalvikvm(741): GC_BEFORE_OOM freed 8K, 34% free 17685K/26631K, paused 142ms
03-23 16:32:52.242: E/dalvikvm-heap(741): Out of memory on a 16777232-byte allocation.
03-23 16:32:52.242: I/dalvikvm(741): "Thread-12" prio=5 tid=10 RUNNABLE
03-23 16:32:52.251: I/dalvikvm(741): | group="main" sCount=0 dsCount=0 obj=0x408b9158 self=0x16f860
03-23 16:32:52.251: I/dalvikvm(741): | sysTid=752 nice=0 sched=0/0 cgrp=default handle=1669016
03-23 16:32:52.251: I/dalvikvm(741): | schedstat=( 5912317448 1115812658 845 ) utm=511 stm=80 core=0
03-23 16:32:52.251: I/dalvikvm(741): at org.apache.http.util.CharArrayBuffer.expand(CharArrayBuffer.java:~59)
03-23 16:32:52.251: I/dalvikvm(741): at org.apache.http.util.CharArrayBuffer.append(CharArrayBuffer.java:77)
03-23 16:32:52.251: I/dalvikvm(741): at org.apache.http.util.EntityUtils.toString(EntityUtils.java:136)
03-23 16:32:52.251: I/dalvikvm(741): at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146)
03-23 16:32:52.251: I/dalvikvm(741): at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:76)
03-23 16:32:52.251: I/dalvikvm(741): at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:59)
03-23 16:32:52.251: I/dalvikvm(741): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:657)
03-23 16:32:52.262: I/dalvikvm(741): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:627)
03-23 16:32:52.262: I/dalvikvm(741): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:616)
03-23 16:32:52.262: I/dalvikvm(741): at com.shr.khg.MainScreen.login(MainScreen.java:170)
03-23 16:32:52.262: I/dalvikvm(741): at com.shr.khg.MainScreen.access$0(MainScreen.java:118)
03-23 16:32:52.262: I/dalvikvm(741): at com.shr.khg.MainScreen$1.run(MainScreen.java:79)
03-23 16:32:55.752: W/dalvikvm(741): threadid=10: thread exiting with uncaught exception (group=0x40014760)
03-23 16:32:55.772: E/AndroidRuntime(741): FATAL EXCEPTION: Thread-12
03-23 16:32:55.772: E/AndroidRuntime(741): java.lang.OutOfMemoryError
03-23 16:32:55.772: E/AndroidRuntime(741): at org.apache.http.util.CharArrayBuffer.expand(CharArrayBuffer.java:59)
03-23 16:32:55.772: E/AndroidRuntime(741): at org.apache.http.util.CharArrayBuffer.append(CharArrayBuffer.java:77)
03-23 16:32:55.772: E/AndroidRuntime(741): at org.apache.http.util.EntityUtils.toString(EntityUtils.java:136)
03-23 16:32:55.772: E/AndroidRuntime(741): at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146)
03-23 16:32:55.772: E/AndroidRuntime(741): at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:76)
03-23 16:32:55.772: E/AndroidRuntime(741): at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:59)
03-23 16:32:55.772: E/AndroidRuntime(741): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:657)
03-23 16:32:55.772: E/AndroidRuntime(741): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:627)
03-23 16:32:55.772: E/AndroidRuntime(741): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:616)
03-23 16:32:55.772: E/AndroidRuntime(741): at com.shr.khg.MainScreen.login(MainScreen.java:170)
03-23 16:32:55.772: E/AndroidRuntime(741): at com.shr.khg.MainScreen.access$0(MainScreen.java:118)
03-23 16:32:55.772: E/AndroidRuntime(741): at com.shr.khg.MainScreen$1.run(MainScreen.java:79)
03-23 16:32:59.012: I/Process(741): Sending signal. PID: 741 SIG: 9
Thanks!
It is a very known problem.... First of all you ought to implement your http request in AsyncTask.... Then you won't see this error never Again!!!!!!!!!!!!!