Categories
discuss

When should I close an SQLiteDatabase object?

I kept getting this annoying runtime error for hours, which crashed my app:

java.lang.RuntimeException: An error occured while executing doInBackground().

Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase

After some debugging I found that it happens because I close my SQLiteDatabse object, in the onDestory() method. It happens when I call SQLiteOpenHelper.close() as well.

@Override
protected void onDestroy() {
    super.onDestroy();
    _cursor.close(); //is fine
    _db.close(); //causes error
    _databaseHelper.close(); //causes error too (probably calls db.close() internally..?)
    SharedFunctions.d("closed!"); //ignore this ugly thing
}

This brings up the two questions

  1. Am I doing it right? (probably not)
  2. When do I need to close a SQLiteDatabase object, if not in the onDestroy method?

Edit: The DB and the Helper classes are static:

public class MainActivity extends Activity {

    private Cursor _cursor = null;
    private MyCursorAdapter _myCursorAdapter = null;
    private ListView _listView = null;

    private static SalaryDatabaseHelper _databaseHelper = null;
    public static SQLiteDatabase db = null;

    ...

I initialize _databaseHelper in the onCreate() method:

//get database helper
        if(_databaseHelper == null)
            _databaseHelper = SalaryDatabaseHelper.getInstance(this);

db is initialized in an AsyncTask.doInBackground():

protected Boolean doInBackground(Integer... data)
{
    try {
        //get writable database
        if(db == null)
            db = SalaryDatabaseHelper.getDbInstance();

I use singletons for the helper class and the database class: (both accessed via the helper class)

class MyDatabaseHelper extends SQLiteOpenHelper{

    private static SalaryDatabaseHelper _instance = null;
    private static SQLiteDatabase _dbInstance = null;

    //singletons
    public static synchronized SalaryDatabaseHelper getInstance(Context context)
    {
        // Use the application context, which will ensure that you
        // don't accidentally leak an Activity's context.
        if (_instance == null)
            _instance = new SalaryDatabaseHelper(context.getApplicationContext());

        return _instance;
    }

    public static synchronized SQLiteDatabase getDbInstance() {
        if(_dbInstance == null)
            _dbInstance = _instance.getWritableDatabase();

        return _dbInstance;
    }

    ...

Answer

Your SQLiteOpenHelper instance is static, and therefore global in scope. With that in mind:

Am I doing it right? (probably not)

No.

When do I need to close a SQLiteDatabase object, if not in the onDestroy method?

Never. SQLite is transactional. There is no risk from failing to close the database.

Yes, this irks me too, but I have gone through the seven stages of grief over this, and I am on to “acceptance”

In simpler scenarios, where there is a single component with access to the database, you might close it when that component is destroyed. In your case, your whole app, including background threads, have access to the database. In that case, you simply never close it.

Categories
discuss

Angular 2/4 – best pratice of getting a variable from service in all html files of components?

I have alert service in a angular 4 project. All components can set alerts in that service, but only some show them and each one shows them in a unique location. So my question is how is it possible to define get a variable from a service in all the html files?

My service looks like this:

import { Injectable } from '@angular/core';

@Injectable()
export class AlertService {
  message;

  constructor() { }

  setMessage(message){
    this.message = message;
  }
}

And the component that wants to set a message just imports the service and calls setMessage method. But when i try to use message in html file like:

{{message}}

then its out of scope. How can i make this message accessible in all html files of all components?

Or maybe there is a better way to solve this kind of an requirement than a service variable?

Answer

In order to consume the message in your component you need to inject the service in your constructor (which you are probably doing).

Component:

export class MyComponent {
  constructor(public alertService: AlertService)

In the markup reference alertService.message instead of message.

{{ alertService.message }}
Categories
discuss

Automatic library version update for Gradle projects is currently unsupported. Please update your build.gradle manually

I have this in my building.gradle

buildscript {
    ext.kotlin_version = '1.1.2-4'
    ext.kotlin_version = '1.1.2'
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

}

and always show me this

Outdated Kotlin Runtime
        Your version of Kotlin runtime in 'kotlin-stdlib-1.1.2' library is 1.1.2, while plugin version is 1.1.2-release-Studio2.3-5.
        Runtime library should be updated to avoid compatibility problems.

enter image description here

Answer

Update the Kotlin version to 1.1.2-5:

buildscript {
    ext.kotlin_version = '1.1.2-5'
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

}
Categories
discuss

Retrofit 2 + RxJava cancel/unsubscribe

I am performing a network request where I send files and a message. I would like to have an option to cancel current request. I have found two similar questions and both suggests that observable.subscribe(Observer) returns Subscription object which has method unsubscribe().

Here is the first one

And the second one

In my case, I use observable.subscribe(Observer) which is void. Here is my code:

Observable<MessengerRaw> observable = mModel.sendMessage(message, companion, description, multiParts);
        observable.subscribe(new Observer<MessengerRaw>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(MessengerRaw value) {
                if (getView() != null) {
                    ((MessengerActivity) getView()).resetMessegeView();
                    ((MessengerActivity) getView()).updateMessageList();
                }
            }

            @Override
            public void onError(Throwable e) {
                getData().remove(0);
                if (getView() != null) {
                    ((MessengerActivity) getView()).updateMessageList();
                }
            }

            @Override
            public void onComplete() {
                hideProgress();
            }
        });

So how do I unsubscribe/cancel my request? Thank you.

Answer

In RxJava2, you can get Disposable object in onSubscribe callback method of oserver, which you can use to dispose subscription.

Categories
discuss

A function that runs on the second click

I’m running a function that shows a left menu when I click a button.

I need that the menuColapsado() function to run on the first click of the ID menu_button but the function shows the html element on the second click instead of the first. My code is below

function myFunctionxxx() {
  var xxx = document.getElementsByTagName("BODY")[0];
  xxx.style.backgroundColor = "red";
}


$(document).ready(function() {
      $('#menu_links').css({
        width: '50px'
      });
      $('.collapse-menu').addClass('hidden');

      $('ul#menu_links li').hover(function() {
        $('span', this).addClass('show');
        $('span', this).removeClass('hidden');
      }, function() {
        $('span', this).addClass('hidden');
        $('span', this).removeClass('show');
      });


      $("#menu_button").click(function() {
        menuColapsado();
      });

      $('a.test').on("click", function(e) {
        $(this).next('ul').toggle();
        e.stopPropagation();
        e.preventDefault();
      });
      // });





      var clic = 1;

      function menuColapsado() {
        if (clic == 1) {
          $('#menu_links').animate({
            width: '50px'
          }, 350);
          clic = clic + 1;
          $('.collapse-menu').removeClass('show');
          $('.collapse-menu').addClass('hidden');

          $('ul#menu_links li').hover(function() {
            $('span', this).addClass('show');
            $('span', this).removeClass('hidden');
          }, function() {
            $('span', this).addClass('hidden');
            $('span', this).removeClass('show');
          });
        } else {
          $('#menu_links').animate({
            width: '200px'
          }, 350);
          clic = 1;
          $('.collapse-menu').addClass('show');
          $('.collapse-menu').removeClass('hidden');

          $('ul#menu_links li').hover(function() {

          }, function() {
            $('span', this).addClass('show');
            $('span', this).removeClass('hidden');
          });
        }
      }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button type="button" id="menu_button" onclick="myFunctionxxx();"></button>

Answer

So, from what I understand, you have a button and you want to run a function the first time it is clicked and another function the second time it is clicked.

Here is a simple solution with a counter and an If statement:

var timesClicked = 0;

$("#menu_button").click(function() {
    timesClicked++;

    if (timesClicked>1) {
        //run second function
    } else {
        //run first function
    }
})

The above code will run the second function for every other time the button is clicked. You can easily change it to suit your needs if you do not want this to happen.

If you want to use every 3rd, 5th, 7th etc click as a first click and every 4th, 6th, 8th etc click as a second click, you can change the If statement and use modulo division:

var timesClicked = 0;

$("#menu_button").click(function() {
    timesClicked++;

    if (timesClicked%2==0) {
        //run second function
    } else {
        //run first function
    }
})

Check modulo division: How can I use modulo operator (%) in JavaScript?

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..