마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

값을 받아서 DB에 저장시키는 내용입니다...

0 추천
public void dbWrite(String n1) {
 
db.execSQL("UPDATE contact SET name = '" + n1 + "' WHERE _id = "
+ minId + ";");
helper.close();
}
 
스트링값을 받아서 DB 에 저장시키는 건데..
 
value 값은 스트링 하나 입니다.. 
 
 
테이블생성은
db.execSQL("CREATE TABLE contact (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);");
이렇게 했고
 
li2 라는 객체를 만들어서 
li2.dbWrite(b); DB에 값을 저장시키는데 잘안되네요...
 
도움의 손길이 필요합니다 
 
전체적인 상황설명)
A 라는 액티비티에서 확인버튼을 누르면 스트링값이 DB에 저장이 됨과 동시에  (DB 는 이미 초기값을 다 저장해주었음)
B 라는 액티비티로 넘어가는데 , B 액티비티에서는 DB 에 저장된 값을 가지고 listView 형식으로 보여줍니다
 
-- 잘 모르는 부분 은 
확인 버튼을 눌렀을때 li2 객체의 dbWrite 를 호출하는데 널포인터가 뜨더라구요...
 
도와주세요
 
 
Eve[d] (230 포인트) 님이 2014년 1월 9일 질문

1개의 답변

0 추천
li2 객체에서 널포인트가 떴다는건 초기화를 안해주었다는 거네요

소스를 올려보셔야 알 수 있을듯 합니다.
Gradler (109,780 포인트) 님이 2014년 1월 9일 답변
public class ListActivity extends Activity implements
AdapterView.OnItemClickListener {
/** Called when the activity is first created. */
public static Context m_context;
public static String jakmuls[] = new String[10];
static int aa;
dbHelper helper;
SQLiteDatabase db;

// 문자열 저장함수
public void setT(String a) {
try {
String b = "null";
jakmuls[aa] = a;
b = a;
Log.i(null, "jakmul = " + jakmuls[aa]);
// dbWrite(b);
helper.close();
aa++;
} catch (ArrayIndexOutOfBoundsException e) {
Toast.makeText(m_context, "더이상 추가할 수 없습니다.", 1).show();
}
}

public String setT2() {
return jakmuls[aa];
}

// 문자열 반환 함수
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

helper = new dbHelper(this);
db = helper.getWritableDatabase();

Cursor cursor = db.rawQuery("select * from contact", null);
cursor.moveToLast();
minId = cursor.getInt(0);
minScore = cursor.getInt(1);
startManagingCursor(cursor);

String[] from = { "name" };
int[] to = { android.R.id.text1 };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, cursor, from, to);

ListView list = (ListView) findViewById(R.id.list);
list.setAdapter(adapter);

Button gomain = (Button) findViewById(R.id.Gomain);

gomain.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ListActivity.this, SubActivity.class);
startActivity(intent);
}
});
}

public void dbWrite(String n1) {

db.execSQL("UPDATE contact SET name = '" + n1 + "' WHERE _id = "
+ minId + ";");
helper.close();
}

class dbHelper extends SQLiteOpenHelper {

private static final String DATABASE_NAME = "mycontacts.db";
private static final int DATABASE_VERSION = 1;

public dbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);

}

@Override
public void onCreate(SQLiteDatabase db) {

// 테이블 생성
db.execSQL("CREATE TABLE contact (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);");

// 테이블에 초기값 삽입(insert)
for (int i = 0; i < 9; i++) {
db.execSQL("INSERT INTO contact VALUES(null, '비어있음');");
// db.execSQL("INSERT INTO contact VALUES(null, '" + jakmuls[i]
// + "','" + jakmuls[i] + "');");
}
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXITS contact");
onCreate(db);
}

}

@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// TODO Auto-generated method stub
}
}

---------------------------------------------------------------------------------------------------
public class TomatoSelect extends Activity {
ArrayAdapter<CharSequence> adspin; // 종류
String a = "z"; // 체크박스
String selItem = "z"; // 스피너 선택한거
Context m_context;
ListActivity li2 = new ListActivity();
CheckBox c1, c2, c3;


public TomatoSelect(){
}
public TomatoSelect(Context context){
m_context = context;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tomatoselect);


// 테이블의 모든 레코드를 커서객체로 가져온다.

c1 = (CheckBox) findViewById(R.id.checkBox1);
c2 = (CheckBox) findViewById(R.id.checkBox2);
c3 = (CheckBox) findViewById(R.id.checkBox3);

Button buttonCheck = (Button) findViewById(R.id.check);
Button buttonEnd = (Button) findViewById(R.id.cancle);

c1.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@SuppressLint("ShowToast")
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (buttonView.getId() == R.id.checkBox1) {
if (isChecked) {

} else {
}
}
}
});
c2.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@SuppressLint("ShowToast")
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (buttonView.getId() == R.id.checkBox2) {
if (isChecked) {
} else {
}
}
}
});
c3.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@SuppressLint("ShowToast")
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (buttonView.getId() == R.id.checkBox3) {
if (isChecked) {
} else {
}
}
}
});

final Spinner spin = (Spinner) findViewById(R.id.spinner1);

spin.setPrompt("종류를 고르세요");

adspin = ArrayAdapter.createFromResource(this, R.array.jakmul_array,
android.R.layout.simple_spinner_dropdown_item);
adspin.setDropDownViewResource(android.R.layout.simple_spinner_item);
spin.setAdapter(adspin);

// 스피너의 리스너 값이 선택되었을때의
spin.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
try{
selItem = (String) spin.getSelectedItem();
}
catch(ArrayIndexOutOfBoundsException e){
//if(ListActivity.jakmuls[9]!=null){
Toast.makeText(getApplicationContext(), "더이상 추가할 수 없습니다.",
1).show();
//}
}
Log.i(null, selItem);
}

// 아무것도 선택되어 있지 않을때
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
// 확인 버튼을 누르면 총체적으로 확인하는 엑티비티로 넘어간다.
buttonCheck.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// li2.setT(selItem);
Intent intent = new Intent(TomatoSelect.this,
ListActivity.class);
Log.i(null, selItem);
// li2.dbWrite(selItem); << 이부분 널포인터 예외 ...
li2.setT(selItem);

startActivityForResult(intent, 0);
}
});
// 취소 버튼을 누를시 뒤로가게 된다.
buttonEnd.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// moveTaskToBack(true);
finish();
// android.os.Process.killProcess(android.os.Process.myPid());
}
});
}
}



------------- 주요 액티비티 2개 입니다
액티비티를 상속받은 클래스를 일반 클래스처럼 똑같이 사용하려고 하셔서 발생한 문제입니다.  지금 짜놓으신소스로는 간단히 해결하려고 하지 말고 아래 드리는 조언대로 다시 만드시기 바랍니다.

1. 디비 헬퍼 클래스는 따로 클래스파일로 만들고 db에 접근해서 쓰거나 삭제 등을 담당하는 메소드는 해당 클래스에 구현한다.
2. 디비에 대한 접근(쓰기 읽기 조회 등)은 일회성으로 열었다가 사용이 끝나면 즉시 close 시킨다.
3. Activity를 상속한 클래스를 다른 액티비티에서 생성해서 사용하는 방법은 안됩니다. 헬퍼클래스를 각 필요한 클래스에서 초기화해서 사용한다.
그러면 한가지 더 여쭤볼게요,

1. 헬퍼클래스를 구현했습니다.
2. db에서 Write 를 하려고할때, 메소드를 하나 구현해서 작업을 했는데,
db에 들어가는 값이 String 값으로 두개 입니다 .
name , desc
이때, SQL 문을 잘모르겠네요;;
db.execSQL("UPDATE contact SET name = '" + n1 + "' WHERE _id = "
                + minId + ";");
        db.execSQL("UPDATE contact SET desc = '" + n1 + "' WHERE _id = "
                + minId + ";");

이런식으로 구현했는데..
방법은 매우 다양합니다.

public void dbUpdate(String content, String value, long id) {
    db.execSQL("UPDATE contact SET " + content + "'" + n1 + "' WHERE _id = "  + id + ";");
}

메소드를 위와 같이 정의해놓고

dbWrite("name", n1, minId);
dbWrite("desc", n1, minId);

이렇게 메소드를 두번 호출하는 방법도 있고,


다음과 같은 메소드로 만들어서

public void dbUpdate(ContentValues values, long id) {       
    db.update("contact", values, "_id=", id);
}

이렇게 호출하는 방법도 있습니다.

ContentValues values = new ContentValues();
values.put("name", n1);
values.put("desc", n1);
dbUpdate(values, minId);

구현은 본인의 몫입니다..
귀찮게 해드려서 죄송하지만 하나만 더 질문할게요 ㅠㅠ
DB에 저장된 값을 리스트뷰에 띄우려고 하는데,,

// 테이블의 모든 레코드를 커서객체로 가져온다.
Cursor cursor = db.rawQuery("select * from data", null);
        cursor.moveToLast();
        minId = cursor.getInt(0);
        minScore = cursor.getInt(1);

        String[] from = { "name","desc" };
        int[] to = { android.R.id.text1 };
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_1, cursor, from, to);

        ListView list = (ListView) findViewById(R.id.list);
        list.setAdapter(adapter);

이런식으로 추가해서 구현하면 될까요?...
=================================
public void dbUpdate(String content, String value, int id) {
        db = helper.getWritableDatabase();
        db.execSQL("UPDATE data SET name = '" + content + "' WHERE _id = "
                + minId + ";");
        db.execSQL("UPDATE data SET desc = '" + value + "' WHERE _id = "
                + minId + ";");
        db.execSQL("UPDATE data SET score = " + id + " WHERE _id = " + minId
                + ";");
        helper.close();
    }

제가 이런식으로 구성해서

buttonCheck.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent(TomatoSelect.this,
                        SubActivity.class);
                Log.i(null, selItem);
                dbUpdate("name", selItem, minId);
                dbUpdate("desc", a, minId);
                // li2.setT(selItem);
                startActivity(intent);
            }
        });

이런식으로 했는데...
db = helper.getWritableDatabase();
이 구문에서 널포인터예외가 일어나네요;;;


디비헬퍼 클래스는 이렇게 구현했습니다.
public class DBHelper extends SQLiteOpenHelper {
    public DBHelper(Context context) {
        super(context, "DataDB.db", null, 1);
    }

    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE data ( _id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, dsec TEXT, score INTEGER);");
    }

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS data");
        onCreate(db);
    }
}

조언 부탁드릴게요
주말동안에는 들어와보지 않기 때문에 늦게 봤네여
onCreate 구문에서 db = new DBHelper(this);
이런식의 초기화를 해주셨는지요
helper = new DBHelper(m_context); 이런식으로 초기화 해줬구...
에러는

public void dbInit() {
        db = helper.getWritableDatabase();
디비초기화 함수에서 첫째줄부터 널포인터 가 나네요...
전체 소스를 다 보여드리고 싶지만 조금 길이가 있네요..
그 onCreate 구문이 DBHelper 에 있는것 말씀하신건가요?
...