0

I am currently polishing my apps offline features.

Before those offline features, if I remember correctly, works as I what and of course as it should be. There is a feature where my app calculates or estimates the bill per month of a household and put it in a text view.

It works fine, but the problem is when I return to my main activity and return to that where the computations are done the value of the text view is cleared and when I look at the logcat it’s like the app starts a new computation again while the old computation continues. And even if there’s 2 computations running at the background, it takes some time before the text view for the bill per month gain value again. And sometimes, it uses the new computation’s result for its value. I’ve used or done something to be able to come up with what I need but to no avail. You can see it in the onCreate and onResume of the activity. Here’s the code for that activity:

public class ListViewForm extends Activity {
    privateCustomCursorAdaptercustomAdapter;
    privateTodoItemDatabase td;
    GlobalVariablesgv = new GlobalVariables();

    privateListView lv;
    Switch swi;

    intdevId, devPos;
    long devId2;
    String devName;
    intdevWatt, devStat;

    //bill
    int id, watt, stat;
    String name;

    //for timer
    Timer timer;
TimerTasktimerTask;
    Handler handler, adapter;

    //for bill compute
inttotalWatt, timerFirstRun;
inttotalHour = 1;
doublewattHourPerDay, kiloWattPerDay, kiloWattPerMonth;

TextViewlblBillVal;
OnItemClickListeneritemClick;

    //global variables
doublecostPerMonth = gv.costPerMonth;
int delay = gv.notifDuration;
doublebillForMonth = gv.billForMonth;

    //also for bill compute
doublebillPerMonth;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_view_form);

        lv = (ListView)findViewById(R.id.list_data);
        lv.setItemsCanFocus(false);
        lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

        lblBillVal = (TextView)findViewById(R.id.lblBillValue);
        lblBillVal.setText("");

        swi = (Switch)findViewById(R.id.switchGCM);
        //itemClick

        itemClick = new OnItemClickListener(){

            @Override
            public void onItemClick(AdapterView<?> parent, View v, intpos, long id) {
                Log.d("batelec", "id: "+id+" pos: "+pos);
                TodoItemDatabase td = new TodoItemDatabase(getBaseContext());
                int x = Integer.valueOf(String.valueOf(id));
                Cursor cur = td.getOneRow(x);
                if(cur != null){
                    if(cur.moveToFirst()){
                        Log.d("batelec", "inside onitemclick, cur count: "+cur.getCount());
                        devStat = cur.getInt(cur.getColumnIndex(cur.getColumnName(3)));
                        Log.d("batelec", "1st devStat: "+devStat);
                        if(devStat == 0){
                            devStat = 1;
                        }
                        else{
                            devStat = 0;
                        }

                        devId = cur.getInt(cur.getColumnIndex(cur.getColumnName(0)));
                        devName = cur.getString(cur.getColumnIndex(cur.getColumnName(1)));
                        devWatt = cur.getInt(cur.getColumnIndex(cur.getColumnName(2)));
                        //devStat
                        Log.d("batelec", "2nd devStat: "+devStat);
                        td.updateStat(new TodoItem(devId, devName, devWatt, devStat));

                        CustomCursorAdaptercr = new CustomCursorAdapter(ListViewForm.this, td.getAllData());
                        cr.notifyDataSetChanged();
                        lv.setAdapter(cr);
                    }

                }
            }

        };
        lv.setOnItemClickListener(itemClick);
        //itemLongClick
        lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            publicbooleanonItemLongClick(AdapterView<?> parent, View v, intpos, long id){
                Log.d("batelec", "longclick");

                returnonLongListItemClick(v, pos, id);
            }
        });

        td = new TodoItemDatabase(this);
        new Handler().post(new Runnable(){
            @Override
            public void run(){
                customAdapter = new CustomCursorAdapter(ListViewForm.this, td.getAllData());
                lv.setAdapter(customAdapter);
            }
        });

        useHandler();
        if(billForMonth != 0){
            Log.d("Batelec", "billForMonth: "+billForMonth);
            billPerMonth = billForMonth;
        }
    }
    //itemLongClick
    protectedbooleanonLongListItemClick(View v, final intpos, long id) {
    Log.d("batelec", "onLongListItemClick id= " + id + " position= " + pos);

        devId2 = id;
    devPos = pos;
    final Dialog dialog = new Dialog(ListViewForm.this);
        dialog.setContentView(R.layout.dialog_form_design);
        dialog.setTitle("Option");
        Button btnEdit = (Button)dialog.findViewById(R.id.btnMainRegister);
        Button btnDelete = (Button)dialog.findViewById(R.id.dialogBtnDelete);

        btnEdit.setOnClickListener(new OnClickListener(){
            public void onClick(View v){
                TodoItemDatabase td = new TodoItemDatabase(ListViewForm.this);
                Cursor cur = td.getAllData();

                if(cur!=null){
                    if(cur.moveToFirst()){
                        cur.moveToPosition(pos);
                        devId = cur.getInt(cur.getColumnIndex("_id"));
                        devName = cur.getString(cur.getColumnIndex("deviceName"));
                        devWatt = cur.getInt(cur.getColumnIndex("deviceWattage"));
                        devStat = cur.getInt(cur.getColumnIndex("deviceStatus"));
                        Log.d("batelec", "devID: "+devId+" devName: "+devName+" devWatt: "+devWatt+" devStat: "+devStat);
                    }
                }
                Intent i = new Intent(getBaseContext(),AddDeviceForm.class);
                Bundle b = new Bundle();
                Log.d("batelec", "sent id: "+devId);
                b.putInt("xtraDevId", devId);
                b.putString("xtraDevName", devName);
                b.putInt("xtraWatt", devWatt);
                b.putInt("xtraStat", devStat);
                Log.d("batelec", "sent devStat: "+devStat);
                i.putExtras(b);
                startActivity(i);
                finish();
            }
        });

        btnDelete = (Button)dialog.findViewById(R.id.dialogBtnDelete);
        btnDelete.setOnClickListener(new OnClickListener(){
            public void onClick(View v){

                TodoItemDatabase td = new TodoItemDatabase(ListViewForm.this);
                Cursor cur = td.getAllData();

                if(cur!=null){
                    if(cur.moveToFirst()){
                        cur.moveToPosition(pos);
                        devId = cur.getInt(cur.getColumnIndex("_id"));
                        devName = cur.getString(cur.getColumnIndex("deviceName"));
                        devWatt = cur.getInt(cur.getColumnIndex("deviceWattage"));
                        devStat = cur.getInt(cur.getColumnIndex("deviceStatus"));
                        devPos = pos;
                        Log.d("batelec", "devID: "+devId+" devName: "+devName+" devWatt: "+devWatt+" devStat: "+devStat+" devPos: "+devPos);
                    }
                }
                Bundle b = new Bundle();
                b.putInt("xtraId", devId);
                b.putInt("xtraPos", devPos);
                DialogFragmentdeleteDiag = new DeleteDialog();
                deleteDiag.setArguments(b);
                deleteDiag.show(getFragmentManager(), "deleteDevice");
            }
        });

        dialog.show();
        Log.d("batelec", "showing dialog");
    return true;
    }

    public void useHandler(){
        handler = new Handler();
        handler.postDelayed(runnable, 1000);
    }
    public void stopRunnable(View v){
        handler.removeCallbacks(runnable);
    }

    private Runnable runnable = new Runnable(){
        @Override
        public void run(){
            TodoItemDatabase td = new TodoItemDatabase(getBaseContext());
            Cursor cur = td.getActiveDevice();

            if(timerFirstRun == 0){
                timerFirstRun++;
                Log.d("batelec", "timer = 0");
            }
            else{
                try{
                    if(cur != null){
                        Toast.makeText(getBaseContext(), "1 hour elapsed", Toast.LENGTH_LONG).show();

                        cur.moveToFirst();
                        for(int x = 1; x <= cur.getCount(); x++){
                            id = cur.getInt(cur.getColumnIndex("_id"));
                            name = cur.getString(cur.getColumnIndex("deviceName"));
                            watt = cur.getInt(cur.getColumnIndex("deviceWattage"));
                            stat = cur.getInt(cur.getColumnIndex("deviceStatus"));

                            totalWatt = totalWatt + watt;
                            Log.d("batelec", "id: " + id + " name: " + name + " watt: " + watt + " status: " + stat);
                            cur.moveToNext();
                        }
                        //totalWatt = 125;
                        Log.d("batelec", "total watt: "+totalWatt);

                        wattHourPerDay = totalWatt;//all active device wattage 
                        Log.d("batelec", "wattPerHour: "+wattHourPerDay+" (totalWatt)");

                        kiloWattPerDay = wattHourPerDay / 1000;//all device watts divided by 1000 watts = 1 kW
                        Log.d("batelec", "kilowatt per day: "+kiloWattPerDay+" (wattPerHour / 1000)");

                        kiloWattPerMonth = (wattHourPerDay * 30) / 1000;//watts per month
                        Log.d("batelec", "kiloWatt per month: "+kiloWattPerMonth+" ((wattPerHour * 30) / 1000)");

                        billPerMonth = kiloWattPerMonth * costPerMonth;//estimated bill per month
                        Log.d("batelec", "bill per month: "+billPerMonth+" (kiloWattPerMonth * costPerMonth)");


                        Double res;
                        DecimalFormatdf = new DecimalFormat("#.##");
                        res = Double.valueOf(df.format(billPerMonth));

                        Log.d("batelec", "new bill: "+res);

                        lblBillVal.setText(String.valueOf(res));
                    }
                }catch(Exception e){
                    Log.d("batelec", ""+e);
                }
            }
            handler.postDelayed(runnable, delay);

            //send billPerMonth to Global Variables

            gv.billForMonth = billPerMonth;
        }

    };

    public void onResume(){
        super.onResume();
        Log.d("Batelec", "inside listviewformonResume");
        billPerMonth = gv.billForMonth;
    }
}

Here is the logcat log:

09-08 09:14:43.130: D/batelec(1081): id: 2 name: Incandescent Bulb watt: 40 status: 1
09-08 09:14:43.130: D/batelec(1081): total watt: 40
09-08 09:14:43.140: D/batelec(1081): wattPerHour: 40.0 (totalWatt)
09-08 09:14:43.140: D/batelec(1081): kilowatt per day: 0.04 (wattPerHour / 1000)
09-08 09:14:43.140: D/batelec(1081): kiloWatt per month: 1.2 ((wattPerHour * 30) / 1000)
09-08 09:14:43.140: D/batelec(1081): bill per month: 10.26816 (kiloWattPerMonth * costPerMonth)
09-08 09:14:43.160: D/batelec(1081): new bill: 10.27
09-08 09:15:01.930: D/Batelec(1081): inside listviewformonResume
09-08 09:15:04.340: D/batelec(1081): timer = 0
09-08 09:15:04.690: D/batelec(1081): Name: Microwave Stat: 0
09-08 09:15:04.890: D/batelec(1081): Name: Incandescent Bulb Stat: 1
09-08 09:15:33.270: D/batelec(1081): id: 2 name: Incandescent Bulb watt: 40 status: 1
09-08 09:15:33.270: D/batelec(1081): total watt: 80
09-08 09:15:33.270: D/batelec(1081): wattPerHour: 80.0 (totalWatt)
09-08 09:15:33.280: D/batelec(1081): kilowatt per day: 0.08 (wattPerHour / 1000)
09-08 09:15:33.280: D/batelec(1081): kiloWatt per month: 2.4 ((wattPerHour * 30) / 1000)
09-08 09:15:33.280: D/batelec(1081): bill per month: 20.53632 (kiloWattPerMonth * costPerMonth)
09-08 09:15:33.280: D/batelec(1081): new bill: 20.54
09-08 09:15:54.480: D/batelec(1081): id: 2 name: Incandescent Bulb watt: 40 status: 1
09-08 09:15:54.480: D/batelec(1081): total watt: 40
09-08 09:15:54.490: D/batelec(1081): wattPerHour: 40.0 (totalWatt)
09-08 09:15:54.490: D/batelec(1081): kilowatt per day: 0.04 (wattPerHour / 1000)
09-08 09:15:54.490: D/batelec(1081): kiloWatt per month: 1.2 ((wattPerHour * 30) / 1000)
09-08 09:15:54.490: D/batelec(1081): bill per month: 10.26816 (kiloWattPerMonth * costPerMonth)
09-08 09:15:54.490: D/batelec(1081): new bill: 10.27
09-08 09:16:23.390: D/batelec(1081): id: 2 name: Incandescent Bulb watt: 40 status: 1
09-08 09:16:23.390: D/batelec(1081): total watt: 120
09-08 09:16:23.390: D/batelec(1081): wattPerHour: 120.0 (totalWatt)
09-08 09:16:23.400: D/batelec(1081): kilowatt per day: 0.12 (wattPerHour / 1000)
09-08 09:16:23.400: D/batelec(1081): kiloWatt per month: 3.6 ((wattPerHour * 30) / 1000)
09-08 09:16:23.400: D/batelec(1081): bill per month: 30.804480000000005 (kiloWattPerMonth * costPerMonth)
09-08 09:16:23.400: D/batelec(1081): new bill: 30.8
09-08 09:16:44.620: D/batelec(1081): id: 2 name: Incandescent Bulb watt: 40 status: 1
09-08 09:16:44.620: D/batelec(1081): total watt: 80
09-08 09:16:44.630: D/batelec(1081): wattPerHour: 80.0 (totalWatt)
09-08 09:16:44.630: D/batelec(1081): kilowatt per day: 0.08 (wattPerHour / 1000)
09-08 09:16:44.640: D/batelec(1081): kiloWatt per month: 2.4 ((wattPerHour * 30) / 1000)
09-08 09:16:44.640: D/batelec(1081): bill per month: 20.53632 (kiloWattPerMonth * costPerMonth)
09-08 09:16:44.650: D/batelec(1081): new bill: 20.54

As you can see there are 2 computations running but the newest or the one with the lower values is used by the app. I don’t know why that happens and I don’t remember doing something to my app to do that. I just added GCM to my app, will it affect my offline features. Please help.

Vadim Caen
  • 1,526
  • 11
  • 21
halfBlue3
  • 13
  • 8
  • Maybe do some base level analysis of your logic to see why its starting twice? You wrote the logic, you should be familiar with why its starting two runables. Do your own code analysis first and provide that feedback. Also look at your logs, if its not useful add more debugging logs. Make your code debuggable, don't leave yourself guessing whats wrong. Know your states and behavior. – JoxTraex Sep 11 '15 at 10:22
  • if i remember it right, those thing doesn't happen before – halfBlue3 Sep 11 '15 at 10:36
  • That doesn't mean you shouldn't do analysis on your side to validate what exactly changed by doing some base level analysis with your logs. – JoxTraex Sep 11 '15 at 10:37
  • 1
    hey, i kinda think after a lot running, running my app and just doing a very, very small amount of fixing my code because i can't really see anything that will make it act that way, my app starts a new calculation every time a go to that activity. as I've researched, i found out about threads. i guess that's the reason why my app run two runnables. it seems that when i go out of the activity, the thread dies and runs a new one again if i go to that activity. can someone teach me more about thread handling. and please don't use examples that need internet connection cause its not what i need – halfBlue3 Sep 14 '15 at 08:25
  • Great! Now that you have an idea of why this is being done. Now you can diagnose the issue. So just so you're aware threading has nothing to do with internet connection. So approach threading as an abstract concept that you are utilizing to do your bidding. – JoxTraex Sep 14 '15 at 18:31
  • i got another thing that runs using handler, my local notification. what i don't understand is why do my local notification runs fine. it never stops unlike my electric bill calculator or estimator. why do you think my app stops my bill calculator and keeps my local notification run the way it should? – halfBlue3 Sep 15 '15 at 10:21

0 Answers0