package com.example.a0606;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelStore;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.HorizontalScrollView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private DataBaseHelp helper=null;
private OperateTable mytable=null;
private EditText name,sex,email;
private Button zj,sc,xg,cx;
private static int count=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.zj=(Button) findViewById(R.id.zj);
this.cx=(Button) findViewById(R.id.cx);
this.xg=(Button) findViewById(R.id.xg);
this.sc=(Button) findViewById(R.id.sc);
this.helper=new DataBaseHelp(this);
this.sc.setOnClickListener(new sc());
this.zj.setOnClickListener(new zj());
this.xg.setOnClickListener(new xg());
this.cx.setOnClickListener(new cx());
}
private class zj implements View.OnClickListener{
@Override
public void onClick(View view) {
OperateTable mytable=new OperateTable(helper.getWritableDatabase());
mytable.insert("lgx"+count++,"女","l123@qq.com");
}
}
private class sc implements View.OnClickListener{
@Override
public void onClick(View view) {
OperateTable mytable=new OperateTable(helper.getWritableDatabase());
mytable.delete(5);
}
}
private class xg implements View.OnClickListener{
@Override
public void onClick(View view) {
OperateTable mytable=new OperateTable(MainActivity.this.helper.getWritableDatabase());
mytable.update(1,"wangwu","男","wangwu456@qq.com");
}
}
private class cx implements View.OnClickListener{
@Override
public void onClick(View view) {
MainActivity.this.helper = new DataBaseHelp(MainActivity.this);
ListView listView = new ListView(MainActivity.this);
listView.setAdapter(new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1,
new OperateTable(helper.getReadableDatabase()).find()));
}
}
}
package com.example.a0606;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
public class DataBaseHelp extends SQLiteOpenHelper{
private static final String DATABASENAME="lgx.db";
private static final int DATABASEVERSION=1;
private static final String TABLENAME="personinfo";
public DataBaseHelp(Context context){
super(context,DATABASENAME,null,DATABASEVERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql="CREATE TABLE "+TABLENAME+"("+
"id IBTEGER PRIMARY KEY ,"+
"name VARCHAR(50) NOT NULL ,"+
"sex VARCHAR(50) NOT NULL ,"+
"email VARCHAR(50) NOT NULL)";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql="DROP TABLE IF EXISTS "+TABLENAME;
db.execSQL(sql);
this.onCreate(db);
}
}
package com.example.a0606;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class OperateTable {
private static final String TABLENAME ="personinfo";
private SQLiteDatabase db = null;
public OperateTable(SQLiteDatabase db){
this.db=db;
}
public void insert(String name, String sex,String email) {
String sql = "INSERT INTO " + TABLENAME + "(name, sex,email) VALUES ('" + name + "', '" + sex + "','" + email + "')";
this.db.execSQL(sql);
this.db.close();
}
public void update(int id, String name, String sex,String email) {
String sql="UPDATE"+ TABLENAME + " SET name= '"+ name+ "',sex= '"+ sex + "',email='"+ email + "WHERE id="+ id;
this.db.execSQL(sql);
this.db.close();
}
public void delete(int id) {
String sql = "DELETE FROM "+ TABLENAME +" WHERE id = "+ id;
this.db.execSQL(sql);
this.db.close();
}
public List<String> find(){
List<String> all=new ArrayList<String>();
String sql = "SELECT name,sex,email FROM"+TABLENAME;
Cursor result=this.db.rawQuery(sql,null);
for (result.moveToFirst();!result.isAfterLast();result.moveToNext()){
all.add(result.getString(0)+" "+result.getString(1)+" "+result.getString(2));
}
this.db.close();
return all;
}
}
答案参考ChatGPT ,如果有参考价值麻烦采纳一下,谢谢啦!!_
数据库权限问题:如果应用没有正确申请或者获取数据库读写权限,那么数据库的增、删、改操作都会失败。应用需要在 AndroidManifest.xml 文件中声明需要的权限,例如:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
```
数据库操作语句问题:如果数据库操作语句有误,例如表名、列名、参数等错误,那么操作也会失败。应该仔细检查数据库操作语句的正确性,确保没有错误。
数据库连接问题:如果数据库连接不正确或者已经关闭,那么数据库操作也会失败。应该确保正确获取数据库实例,保持数据库连接有效。
数据库事务问题:如果数据库事务没有正确处理,例如没有提交或者回滚事务,那么数据库修改操作也会失败。应该确保在进行数据库修改操作时,使用事务进行管理。
在检查以上问题的同时,可以使用 Android Studio 的调试工具,例如 Logcat,打印相关错误信息,以便更好地定位问题。另外,也可以尝试使用第三方的数据库操作库,例如 Room,简化数据库操作流程,减少人为错误的可能性。
在android中,对内存的优化是一个app很重要的一个指标,内存优化的比较好的app用起来比较流畅而且出现崩溃的概率会大大降低。 虽然由于科技的发展,使得手机内存越来越高,但是由于引用版本更新迭代以及技术的革新,导致我们的app使用内存也越来越高。
一张图来描述微信各个版本所占用的系统内存:
常见程序程序所占用的内存:
如果内存无法妥善处理好,容易出现如下问题:内存泄漏、内存抖动、内存溢出。
##内存泄漏
Android进程中某些对象(垃圾对象)已经没有使用价值了,比如一个执行了finish的Activity,但是它们却可以直接或间接地被引用到,导致无法被GC回收。无用的对象占据着内存空间,使得实际可使用内存变小,导致应用所需要的内存超过这个系统分配的内存限额,这就造成了内存溢出而导致应用卡顿、最终Crash。
如图:
虽然A、B对象相互调用,或A、B、C三者相互调用,但也是属于垃圾对象,可以被GC检测回收。
###内存泄漏导致的问题
1.导致用户手机可用内存变少
2.程序出现卡顿
3.导致应用莫名退出
4.应用程序Force Close
5.用户流失
#内存泄漏的解决方式
##举例:Handler内存泄漏
1.为什么Handler使用会造成内存泄漏?
熟悉Handler消息机制的都知道,mHandler会作为成员变量保存在发送的消息msg中,即msg持有mHandler的引用,而mHandler是Activity的非静态内部类实例,即mHandler持有Activity的引用,那么我们就可以理解为msg间接持有Activity的引用。msg被发送后先放到消息队列MessageQueue中,然后等待Looper的轮询处理。那么当Activity退出后,msg可能仍然存在于消息队列MessageQueue中未处理或者正在处理,那么这样就会导致Activity无法被回收,以致发生Activity的内存泄露。
2.正确的Handler使用方式(不展示错误的使用方式,避免看到陷入误区)
(1)将Handler声明为静态内部类。因为静态内部类不会持有外部类的引用,所以不会导致外部类实例出现内存泄露。
(2)在Handler中添加对外部Activity的弱引用。由于Handler被声明为静态内部类,不再持有外部类对象的引用,导致无法在handleMessage()中操作Activity中的对象,所以需要在Handler中增加一个对Activity的弱引用。
代码展示:
public class SampleActivity extends Activity {
private final Handler mLeakyHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// ...
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Post a message and delay its execution for 10 minutes.
mLeakyHandler.postDelayed(new Runnable() {
@Override
public void run() { /* ... */ }
}, 1000 * 60 * 10);
// Go back to the previous Activity.
finish();
}
}
链接:http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html
##举例:动画造成的内存泄漏
(1)问题描述
这个问题,也是我在开发过程中经常不注意的一个问题。对于动画在关闭页面没有进行任何cancel的操作或者将动画在不需要的时候只是将执行动画的对象设置为不可见,尤其是那种无限循环的动画,比如属性动画中,将属性动画的执行周期设置为无限循环:animator.setRepeatCount(ValueAnimator.INFINITE);
虽然我们看不到动画了,但是这个动画依然会不断地播放下去,动画引用所在的控件,所在的控件引用Activity,这就造成Activity无法正常释放。
(2)解决方式:
@Override
protected void onDestroy() {
super.onDestroy();
// 取消动画
animator.cancel();
}
不仅包括属性动画,无限循环的动画,最好所有的动画都要在适当的时候进行cancel( )的操作,而且,对于使用动画的控件,也要进行clearAnimation( )的操作。
##举例:WebView使用不合理导致的内存泄漏
分析:关于WebView的泄漏,主要由于Activity释放后,WebView还会持有当前Activity的引用导致。后续新启一篇文章单独介绍。
先附上WebVIew的常用解决方式:
public void destroy() {
if (mWebView != null) {
// 如果先调用destroy()方法,则会命中if (isDestroyed()) return;这一行代码,
// 需要先onDetachedFromWindow(),再destory()
ViewParent parent = mWebView.getParent();
if (parent != null) {
((ViewGroup) parent).removeView(mWebView);
}
mWebView.stopLoading();
// 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
mWebView.getSettings().setJavaScriptEnabled(false);
mWebView.clearHistory();
mWebView.clearView();
mWebView.removeAllViews();
try {
mWebView.destroy();
} catch (Throwable ex) {
}
}
}