ورود

View Full Version : زیاد شدن اطلاعات در sqlite



raha_jon
جمعه 07 شهریور 1393, 17:35 عصر
سلام و ادب و خسته نباشید من ی برنامه ساخته ام اما سرعتش بنظرم خیلی پایینه چون وقتی وارد اکتیویتی میشم که اطلاعات خودشو از بانک اطلاعاتی میگیره یکم طول میکشه که اونم به دلیل زیاد بودن اطلاعات هست میشه کاری کرد زود لود بشه یا هم در هنگام رفتن به اون اکتیویتی یک لطفا منتظر بمانیدی بیاره حداقل تشکر

Rejnev
جمعه 07 شهریور 1393, 17:51 عصر
سلام.
برای افزایش سرعت اصولا یک راهکار خاص وجود نداره.
باید مسئله دقیقا بررسی بشه و چندین راهکار ارائه بشه.
یکیش کم کردن حجم دیتاست... یا اگه امکان پذیر نیست، کم کردن رکوردها یا حتی فیلدهایی که خونده میشن...
برای این که برنامه اصطلاحا Not Responding بشه هم میتونید از تکنیک های چند نخی استفاده کنید. یکی از این روشها که استفاده ازش هم خیلی ساده ست بکارگیری AsyncTask هست که چون مثلا عملیات خوندن دیتا در یک نخ دیگه بجز نخ UI اجرا میشه، لااقل اینترفیس برنامه به حالت هنگ در نمیاد و میتونید اصطلاحا لودینگ برای برنامه بذارین.
اگه مایل بودین یک نمونه کد اینجا قرار میدم.

saeed_g21
جمعه 07 شهریور 1393, 18:13 عصر
آیا موقع اجرای برنامه همه اطلاعات دیتابیس مورد نیازت هست که باید خونده بشه ؟

smemamian
جمعه 07 شهریور 1393, 20:12 عصر
سلام

گفتید که :


به دلیل زیاد بودن اطلاعات هست

این جمله اتون نا مفهوم هستش ! تعداد رکوردهایی که میخونید زیاد هست، یا مقادیری هر رکورد
حجم اطلاعاتی زیادی داره ؟

دوم اینکه اون قسمتی که دارید اطلاعات رو ازدیتابیس می خونید رو بذارید. (زمانی که Activity اجرا میشه
و اطلاعات خوانده میشه منظورم هست.)

raha_jon
شنبه 08 شهریور 1393, 08:58 صبح
آیا موقع اجرای برنامه همه اطلاعات دیتابیس مورد نیازت هست که باید خونده بشه ؟

بله تمام اطلاعات مورد نیاز هست و باید نمایش داده بشه

raha_jon
شنبه 08 شهریور 1393, 08:58 صبح
سلام.
برای افزایش سرعت اصولا یک راهکار خاص وجود نداره.
باید مسئله دقیقا بررسی بشه و چندین راهکار ارائه بشه.
یکیش کم کردن حجم دیتاست... یا اگه امکان پذیر نیست، کم کردن رکوردها یا حتی فیلدهایی که خونده میشن...
برای این که برنامه اصطلاحا Not Responding بشه هم میتونید از تکنیک های چند نخی استفاده کنید. یکی از این روشها که استفاده ازش هم خیلی ساده ست بکارگیری AsyncTask هست که چون مثلا عملیات خوندن دیتا در یک نخ دیگه بجز نخ UI اجرا میشه، لااقل اینترفیس برنامه به حالت هنگ در نمیاد و میتونید اصطلاحا لودینگ برای برنامه بذارین.
اگه مایل بودین یک نمونه کد اینجا قرار میدم.
ممنون میشم کد نمونه قرار بدین

raha_jon
شنبه 08 شهریور 1393, 09:01 صبح
سلام

گفتید که :



این جمله اتون نا مفهوم هستش ! تعداد رکوردهایی که میخونید زیاد هست، یا مقادیری هر رکورد
حجم اطلاعاتی زیادی داره ؟

دوم اینکه اون قسمتی که دارید اطلاعات رو ازدیتابیس می خونید رو بذارید. (زمانی که Activity اجرا میشه
و اطلاعات خوانده میشه منظورم هست.)
باید بگم هم تعداد رکورد ها زیاد هستش و هم مقدار آنها
برای دومی هم این بود که در اکتیویتی ای که اطلاعات خودشو از بانک اطلاعاتی sqlite میگره و نمایش میده.

smemamian
شنبه 08 شهریور 1393, 10:38 صبح
برای دومی هم این بود که در اکتیویتی ای که اطلاعات خودشو از بانک اطلاعاتی sqlite میگره و نمایش میده.


فکر نکنم مشکل شما از خواندن مقادیر زیاد باشه ! مشکل شما این است که دارید از Main Thread
استفاده می کنید.

raha_jon
شنبه 08 شهریور 1393, 16:22 عصر
کد نمونه دارین به این Main Thread

raha_jon
شنبه 08 شهریور 1393, 16:26 عصر
یا هم روشی بگین که یک لودینگ بزارم چون اینو هم بلد نیستم
لطفا
با تشکر

Rejnev
شنبه 08 شهریور 1393, 22:56 عصر
یک نمونه کد میذارم، میتونی طبق اون به هدفی که میخوای برسی:
خب اول کاری میکنم که در قسمت بالای action bar اکتیویتیم امکان نمایش لودینگ بوجود بیاد:


public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}

@Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
setProgressBarVisibility(true);
}
}

حالا با صدا زدن این کد میتونم بگم پروگرس بار نمایش داده بشه:


setProgressBarIndeterminate(true);

و با این کد پنهان بشه:


setProgressBarIndeterminate(false);


حالا وقتشه که وارد بحث AsyncTask بشیم و کاری کنیم تا لود دیتا بصورت موازی در یک نخ دیگه جدای از نخ اصلی (UI) اجرا بشه.

این کد رو داخل کلاس MainActivity بنویسید:

//MyEntity is your Model (with your table structure)
ArrayList<MyEntity> lst;
MyArrayAdapter aa;
LoadData dataLoader;
ListView lv;
Context cx;



@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cx = this;
lv = (ListView) findViewById(R.id.lvMyList);

//create a load and then run it:
dataLoader = new LoadData();
loader.execute();
}

//set data adapter to the list view
private void showDataInListView()
{ aa = new MyArrayAdapter( this, R.item_my_item , lst );
lv.setAdapter(aa);

}

//this class is used when you want to show custom items in the list view
class MyArrayAdapter extends ArrayAdapter<MyEntity>
{
public MyArrayAdapter(Context context, int resource, ArrayList<MyEntity> objects)
{
super(context, resource, objects);
}


@Override
public View getView(int position, View convertView, ViewGroup parent)
{
MyEntity item = getItem(position);
if (convertView == null)
{
convertView = LayoutInflater.from(cx).inflate(R.layout.item_my_i tem, parent, false);
}
TextView tvTitle= (TextView) convertView.findViewById(R.id.tvTitle);
tvTitle.setText(item.name);
return convertView;
}
}



private class LoadData extends AsyncTask<String, String, String>
{
@Override
protected void onPreExecute()
{

super.onPreExecute();
setProgressBarIndeterminate(true);
}
@Override
protected String doInBackground(String... params)
{
//call your data loding functions in here:
lst=MyEntityDal.GetData();
}
return null;
}


@Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
setProgressBarIndeterminate(false);

//this line will be executed after the loading of data is completed
showDataInListView();
}
}

در مثال بالا MyEntity بعنوان مدلی از جدول شما مفروضه. سعی کردم تو قسمتهای مهم کامنت بذارم.

pouya1999best@g
شنبه 08 شهریور 1393, 23:42 عصر
سلام؛
من میخوام برای اولین بار که کاربر وارد برنامه میشه و دیتابیس کپی میشه از تکنیک چند نخی استفاده کنم.
دیتابیسم حدود 1 مگه؛میخوام چند نخی باشه که کاربر کوچک ترین کندی و لگی توی برنامه نبینه.
حالا سوال من اینه که از Theard استفاده کنم یا AsyncTask؟؟؟
عملیات کپی در حدی هست که نمایش پروگرس و... هم نیاز نداره.
فقط میخوام وقتی وارد برنامه شدم سریعا دیتابیس کپی بشه و توی لیست نشون داده بشه.
لطفا کمکم کنید.
ممنونم.

raha_jon
یک شنبه 09 شهریور 1393, 07:36 صبح
معذرت چون زیاد به کد ها مسلط نیستم و خودم ننوشته ام نتونستم پیدا کنم اینم کد هام
مین اکتیویتی

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import ir.esfandune.database.DBAdapter;
import ir.esfandune.database.Dastan;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ListView;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;

public class MainActivity extends ListActivity {
DBAdapter db;
List<Dastan> rah;
ListView lst;

boolean isAll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ctivity_mains);
super.onCreate(savedInstanceState);


isAll =true;// pish farz "All" hast
lst = getListView();
db = new DBAdapter(getBaseContext());
db.open();
Log.i(DBAdapter.TAG, "3");
rah = db.getAllContacts();
Log.i(DBAdapter.TAG, "4");




if (rah.size() == 0) {


String destPath = "/data/data/" + getPackageName() + "/databases";

try {
CopyDB(getBaseContext().getAssets().open("mydb"),
new FileOutputStream(destPath + "/rah"));
Log.i(DBAdapter.TAG, "db copy shod");



rah = db.getAllContacts();

refreshDisplay();

Log.i(DBAdapter.TAG, rah.size() + "= tedad rah");


} catch (FileNotFoundException e) {

e.printStackTrace();
} catch (IOException e) {

e.printStackTrace();
}

} else {
refreshDisplay();
}




}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);

Dastan dastan = rah.get(position);
Intent next = new Intent(this, ShowDastan.class);
next.putExtra("thisdastan", dastan);
startActivity(next);
}


public void CopyDB(InputStream inputStream, OutputStream outputStream)
throws IOException {

byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}

public void refreshDisplay() {
Log.i(DBAdapter.TAG, rah.size() + "= tedad dastanha");


ArrayAdapter<Dastan> adapter = new DastanAdapter(this, rah);



setListAdapter(adapter);
}


@Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
setProgressBarVisibility(true);
}
@Override
protected void onResume() {

super.onResume();

if (isAll) {
rah = db.getAllContacts();
}else {
rah=db.findFAVContacts();
}

refreshDisplay();
}

}

[

Rejnev
یک شنبه 09 شهریور 1393, 20:47 عصر
pouya1999best@g (http://barnamenevis.org/member.php?328146-pouya1999best-g):

با هر دو امکان پذیره، اما چون میخوای نتیجه کار بعد از خوندن تمامی اطلاعات در مثلا لیست ویوو نمایش داده بشه، میتونی AsyncTask استفاده کنی.
این کلاس دو متد مفیدی که داره یکی onPreExecute و onPostExecute هست که هر دو در نخ اصلی اجرا میشن و شما میتونی عملیات قبل و بعد از اجرای نخ رو مثلا توی اونها بنویسی.
یک مثال اینجا از استفاده از AsyncTask میذارم. سعی کنید کارهایی که باید در نخ دیگه انجام بشه رو توی doInBackground قرار بدین:
یک کلاس که از AsyncTask ارث میبره:

private class myTaskClass extends AsyncTask<String, String, String>
{
@Override
protected void onPreExecute()
{
//کارهای قبل از اجرای تسک رو در این قسمت بنویسید
super.onPreExecute();
}


@Override
protected String doInBackground(String... params)
{
//کارهایی که باید در نخ دیگه انجام بشه رو در این متد بنویسید.
//مثلا لود اطلاعات از بانک اطلاعاتی
}


@Override
protected void onPostExecute(String result)
{
//کارهای بعد از اجرای تسک رو در این قسمت بنویسید. مثلا نمایش لیست لود شده در یک لیست ویوو
}
}



این کلاس میتونه توی بخشی از کلاس Activity که الان در اون هستی نوشته بشه.
برای اجرا هم کافیه یک نمونه ازش بسازی، بعد اجراش کنی.

myTaskClass task=new myTaskClass();
task.execute();

ضمنا بین اون دو متد آخر داخل کلاس تسکمون میشه دیتا پاسکاری کرد. برای تغییر نوع دیتا هم میتونی توی قسمتی که سه تا String رو داخل <> گذاشتم، نوع های دلخواه خودت رو بذاری.

myTaskClass task=new myTaskClass();
task.execute("this is a parameter to doInBackground method");

pouya1999best@g
دوشنبه 10 شهریور 1393, 13:09 عصر
معذرت چون زیاد به کد ها مسلط نیستم و خودم ننوشته ام نتونستم پیدا کنم اینم کد هام
مین اکتیویتی

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import ir.esfandune.database.DBAdapter;
import ir.esfandune.database.Dastan;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ListView;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;

public class MainActivity extends ListActivity {
DBAdapter db;
List<Dastan> rah;
ListView lst;

boolean isAll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ctivity_mains);
super.onCreate(savedInstanceState);


isAll =true;// pish farz "All" hast
lst = getListView();
db = new DBAdapter(getBaseContext());
db.open();
Log.i(DBAdapter.TAG, "3");
rah = db.getAllContacts();
Log.i(DBAdapter.TAG, "4");




if (rah.size() == 0) {


String destPath = "/data/data/" + getPackageName() + "/databases";

try {
CopyDB(getBaseContext().getAssets().open("mydb"),
new FileOutputStream(destPath + "/rah"));
Log.i(DBAdapter.TAG, "db copy shod");



rah = db.getAllContacts();

refreshDisplay();

Log.i(DBAdapter.TAG, rah.size() + "= tedad rah");


} catch (FileNotFoundException e) {

e.printStackTrace();
} catch (IOException e) {

e.printStackTrace();
}

} else {
refreshDisplay();
}




}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);

Dastan dastan = rah.get(position);
Intent next = new Intent(this, ShowDastan.class);
next.putExtra("thisdastan", dastan);
startActivity(next);
}


public void CopyDB(InputStream inputStream, OutputStream outputStream)
throws IOException {

byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}

public void refreshDisplay() {
Log.i(DBAdapter.TAG, rah.size() + "= tedad dastanha");


ArrayAdapter<Dastan> adapter = new DastanAdapter(this, rah);



setListAdapter(adapter);
}


@Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
setProgressBarVisibility(true);
}
@Override
protected void onResume() {

super.onResume();

if (isAll) {
rah = db.getAllContacts();
}else {
rah=db.findFAVContacts();
}

refreshDisplay();
}

}

[
میشه نمونه کد بالا رو هم داخل AsyncTask بزارید؟؟؟
ساختار کد های من هم مثل نمونه کد دوستمون هست.

raha_jon
دوشنبه 10 شهریور 1393, 13:31 عصر
از ی جا تغذیه شده ایم دیگه

pouya1999best@g
جمعه 14 شهریور 1393, 16:50 عصر
میشه راهنمایی کنید؟:متفکر:
در ضمن در کلاس AsyncTask نمیتوان از getPackageName و getBaseContext و getApplicationContext استفاده کرد.:متعجب:
چه کنم؟؟؟:اشتباه:

momayyezi_m
جمعه 14 شهریور 1393, 19:55 عصر
ابتدای کار که باید از دوست عزیزمون "Regnev" تشکر کنم ...چون خودمم asynctask بلد نبودم و با این کد یاد گرفتم
ولی در جواب سوال شما باید بگم که طبق اموزش دوست عزیزمون متود کپی رو باید در




@Override
protected String doInBackground(String... params)
{
//کارهایی که باید در نخ دیگه انجام بشه رو در این متد بنویسید.
//مثلا لود اطلاعات از بانک اطلاعاتی
}





قرار بدی

Rejnev
جمعه 14 شهریور 1393, 22:45 عصر
سلام.
علت این که دیر جواب دادم این بود که چون خودم معمولا با جستجو جواب سوالامو پیدا میکنم، دوست داشتم که شما دوستان هم خودتون سعی کنین راه کار رو پیدا کنین. البته بازم بگم، نمیخوام جواب بدم، بلکه یک نمونه کد از کلاسهایی که خودم نوشتم رو میذارم (بخش های اضافه رو حذف میکنم) و سعی کنین با نگاه کردن به اون کد، برنامه خودتون رو اصلاح کنید.
با تشکر.


/*imports...*/
//..
public class Faqs extends Activity
{
ListView lv;
ArrayList<View_Faqs> lstFaqs;
Context cx;
MyArrayAdapter aa;
LoadFaqs loader;
int colorBlack,colorBlackSemi;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_faqs);
resources = getResources();
cx = this;
lv = (ListView) findViewById(R.id.lvFaqs);
loader = new LoadFaqs();
loader.execute();
}


void showLoading()
{
setProgressBarIndeterminate(true);
lv.setVisibility(View.GONE);
}


void hideLoading()
{
setProgressBarIndeterminate(false);
lv.setVisibility(View.VISIBLE);
}


/**
* نمایش لیست لود شده در لیست ویوو
*/
public void loadListView()
{
aa = new MyArrayAdapter(cx, R.layout.item_faqs, lstFaqs);
lv.setAdapter(aa);
}


class MyArrayAdapter extends ArrayAdapter<View_Faqs>
{
public MyArrayAdapter(Context context, int resource, ArrayList<View_Faqs> objects)
{
super(context, resource, objects);
}


@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View_Faqs item = getItem(position);
if (convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout .item_faqs, parent, false);
}
TextView tvQuestion = (TextView) convertView.findViewById(R.id.tvFaqQuestion);
tvQuestion.setTag(item.faqID);
tvQuestion.setText(Html.fromHtml(item.question));
TextView tvVisibleNumber = (TextView) convertView.findViewById(R.id.tvFaqVisibleNumber);
tvVisibleNumber.setText("تعداد مشاهده: " + item.visibleCount);
if (position % 2 == 0)
{
((View) tvVisibleNumber.getParent()).setBackgroundColor(co lorBlack);
}
else
{
((View) tvVisibleNumber.getParent()).setBackgroundColor(co lorBlackSemi);
}
return convertView;
}
}


/*------AsyncTask Use:-------*/
/**
* Load "Co_FaqGroups" list from the DB\
*
*/
private class LoadFaqs extends AsyncTask<String, String, String>
{
@Override
protected void onPreExecute()
{
showLoading();
super.onPreExecute();
}


@Override
protected String doInBackground(String... params)
{
// get list from db.
lstFaqs = FaqDal.getAllByGroup(myGroupID);
return "done";
}


@Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
hideLoading();
// reload listview.
loadListView();
}


@Override
protected void onCancelled()
{
hideLoading();
super.onCancelled();
}


}


@Override
public void onBackPressed()
{
if (loader.getStatus() == Status.RUNNING)
{
//Async task is still running
loader.cancel(true);
}
else
{
super.onBackPressed();
}
}
}

raha_jon
جمعه 21 شهریور 1393, 14:08 عصر
سلام معذرت اینو بالا کشیدم
اما از اون روز که تاپیکو ایجاد کرده ام نتونسته ام اینو پیاده کنم و نمی پرسیدم که بلاخره یاد بگیرم که نشد:گریه:


import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import ir.esfandune.database.DBAdapter;
import ir.esfandune.database.Dastan;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ListView;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;

public class MainActivity extends ListActivity {
DBAdapter db;
List<Dastan> rah;
ListView lst;

boolean isAll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ctivity_mains);
super.onCreate(savedInstanceState);


isAll =true;// pish farz "All" hast
lst = getListView();
db = new DBAdapter(getBaseContext());
db.open();
Log.i(DBAdapter.TAG, "3");
rah = db.getAllContacts();
Log.i(DBAdapter.TAG, "4");




if (rah.size() == 0) {


String destPath = "/data/data/" + getPackageName() + "/databases";

try {
CopyDB(getBaseContext().getAssets().open("mydb"),
new FileOutputStream(destPath + "/rah"));
Log.i(DBAdapter.TAG, "db copy shod");



rah = db.getAllContacts();

refreshDisplay();

Log.i(DBAdapter.TAG, rah.size() + "= tedad rah");


} catch (FileNotFoundException e) {

e.printStackTrace();
} catch (IOException e) {

e.printStackTrace();
}

} else {
refreshDisplay();
}




}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);

Dastan dastan = rah.get(position);
Intent next = new Intent(this, ShowDastan.class);
next.putExtra("thisdastan", dastan);
startActivity(next);
}


public void CopyDB(InputStream inputStream, OutputStream outputStream)
throws IOException {

byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}

public void refreshDisplay() {
Log.i(DBAdapter.TAG, rah.size() + "= tedad dastanha");


ArrayAdapter<Dastan> adapter = new DastanAdapter(this, rah);



setListAdapter(adapter);
}


@Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
setProgressBarVisibility(true);
}
@Override
protected void onResume() {

super.onResume();

if (isAll) {
rah = db.getAllContacts();
}else {
rah=db.findFAVContacts();
}

refreshDisplay();
}

}