作为初学者,我对优化应用程序速度有一些疑问。我正在构建一个简单的测验应用程序,我有一个sqlite数据库里面有一些信息。有了这些信息,我就会在测验页面中生成我的问题。
它工作得很好而且很快,直到我在草图中修复了一些按钮/背景并使用它们。现在它工作得慢得多,我在logcat上收到错误消息,比如“Skipped xxx frames!应用程序可能在其主线程上做了太多工作。”我在google上搜索了一段时间,发现位图正在减慢我的应用程序。已阅读有关异步和使用新线程以使其运行更快的内容。
作为一种解决方案,我已经调整了一些位图,但后来我的设计质量降低了,所以我决定修复它。我已经搜索了更多关于使用异步或新线程加载我的布局但是没有真正了解如何/在哪里做到这一点。令我困惑的是,我不知道是否用新线程加载布局是最好的解决方案,或者用新线程加载其他进程。需要一些关于如何优化我的应用程序的建议。这是我的代码,至少是最慢的测验页面。我不确定用新线程优化什么。在一个问题下,它只是正在运行的倒计时器,当下次点击倒计时器重新开始并且gui用新问题更新时。
我的测验页码:
public class QuizPage extends ActionBarActivity
{
DatabaseHelper dbHelper = new DatabaseHelper(this);
Cursor kommunCrs, lanCrs, riktCrs;
ArrayList<Kommuner> kommunLista = new ArrayList<Kommuner>();
ArrayList<Lan> lanLista = new ArrayList<Lan>();
ArrayList<Riktnummer> riktLista = new ArrayList<Riktnummer>();
ArrayList<Fragar> fragaLista = new ArrayList<Fragar>();
Fragar svList = new Fragar();
Fragar frageObj = new Fragar();
int buttonRaknare = 0;
CountDownTimer cd;
long millisLeft;
long totalMillis = 10100;
int pBarProgress;
TextView pageNr, fraga, cdText;
RadioButton valA, valB, valC, valD;
RadioGroup rg;
Button avsluta, nasta;
ProgressBar pBar;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz_page);
checkDB(); // Checking the DB
getCursorData(); // Getting data to cursors
setCrsdataList(); // Setting cursor data to lists
setViewElements(); // Set textview, buttons etc.
setButtonListeners();
getNastaFragaData(); // Refresing the gui with the next question
startCountdownTimer(totalMillis, false); // Countdowntimer starts
}
private void getCursorData()
{
kommunCrs = dbHelper.getDatabase().query("Kommuner ORDER BY RANDOM() LIMIT 50", new String[]{"kommun_id", "kommun_namn", "kommun_lan", "kommun_befolkning"}, null, null, null, null, null);
lanCrs = dbHelper.getDatabase().query("Lan ORDER BY RANDOM()", new String[]{"lan_namn", "lan_befolkning", "lan_antal_kommun", "lan_yta", "lan_id"}, null, null, null, null, null);
riktCrs = dbHelper.getDatabase().query("Riktnummer ORDER BY RANDOM() LIMIT 50", new String[]{"riktnr", "riktnr_omrade", "riktnr_id"}, null, null, null, null, null);
}
private void setCrsdataList()
{
if (kommunCrs.getCount() != 0 && lanCrs.getCount() != 0 && riktCrs.getCount() != 0) {
kommunCrs.moveToFirst();
lanCrs.moveToFirst();
riktCrs.moveToFirst();
for (int i = 0; i < kommunCrs.getCount(); i++) {
Kommuner tempKommun = new Kommuner();
tempKommun.setKommun_namn(kommunCrs.getString(kommunCrs.getColumnIndex("kommun_namn")));
tempKommun.setKommun_lan(kommunCrs.getString(kommunCrs.getColumnIndex("kommun_lan")));
tempKommun.setKommun_befolkning(kommunCrs.getString(kommunCrs.getColumnIndex("kommun_befolkning")));
tempKommun.setKommun_id(kommunCrs.getInt(kommunCrs.getColumnIndex("kommun_id")));
kommunLista.add(tempKommun);
kommunCrs.moveToNext();
}
for (int i = 0; i < lanCrs.getCount(); i++) {
Lan tempLan = new Lan();
tempLan.setLan_namn(lanCrs.getString(lanCrs.getColumnIndex("lan_namn")));
tempLan.setLan_befolkning(lanCrs.getString(lanCrs.getColumnIndex("lan_befolkning")));
tempLan.setLan_antal_kommun(lanCrs.getString(lanCrs.getColumnIndex("lan_antal_kommun")));
tempLan.setLan_yta(lanCrs.getString(lanCrs.getColumnIndex("lan_yta")));
tempLan.setLan_id(lanCrs.getInt(lanCrs.getColumnIndex("lan_id")));
lanLista.add(tempLan);
lanCrs.moveToNext();
}
for (int i = 0; i < riktCrs.getCount(); i++) {
Riktnummer tempRiktnr = new Riktnummer();
tempRiktnr.setRiktnr(riktCrs.getString(riktCrs.getColumnIndex("riktnr")));
tempRiktnr.setRiktnr_omrade(riktCrs.getString(riktCrs.getColumnIndex("riktnr_omrade")));
tempRiktnr.setRiktnr_id(riktCrs.getInt(riktCrs.getColumnIndex("riktnr_id")));
riktLista.add(tempRiktnr);
riktCrs.moveToNext();
}
//Generating my questions here and taking in to a list
fragaLista = frageObj.slumpaFragor(kommunLista, lanLista, riktLista);
Collections.shuffle(fragaLista);
}
else
{
Toast.makeText(getApplicationContext(), "Finns ingen data i databasen!", Toast.LENGTH_SHORT).show();
}
}
private void getNastaFragaData()
{
fraga.setText(fragaLista.get(buttonRaknare).getFraga());
valA.setText(fragaLista.get(buttonRaknare).getSvarArr().get(0).toString());
valB.setText(fragaLista.get(buttonRaknare).getSvarArr().get(1).toString());
valC.setText(fragaLista.get(buttonRaknare).getSvarArr().get(2).toString());
valD.setText(fragaLista.get(buttonRaknare).getSvarArr().get(3).toString());
pageNr.setText(Integer.toString(buttonRaknare+1) + "/20");
}
private void rattSvarCheck()
{
if (valA.isChecked())
{
fragaLista.get(buttonRaknare).userInput = valA.getText().toString();
if (valA.getText().hashCode() == fragaLista.get(buttonRaknare).getRattSvar().hashCode())
{
svList.antalRattSvar++;
}
else
{
svList.antalFelSvar++;
}
}
else if (valB.isChecked())
{
fragaLista.get(buttonRaknare).userInput = valB.getText().toString();
if (valB.getText().hashCode() == fragaLista.get(buttonRaknare).getRattSvar().hashCode())
{
svList.antalRattSvar++;
}
else
{
svList.antalFelSvar++;
}
}
else if (valC.isChecked())
{
fragaLista.get(buttonRaknare).userInput = valC.getText().toString();
if (valC.getText().hashCode() == fragaLista.get(buttonRaknare).getRattSvar().hashCode())
{
svList.antalRattSvar++;
}
else
{
svList.antalFelSvar++;
}
}
else if (valD.isChecked())
{
fragaLista.get(buttonRaknare).userInput = valD.getText().toString();
if (valD.getText().hashCode() == fragaLista.get(buttonRaknare).getRattSvar().hashCode())
{
svList.antalRattSvar++;
}
else
{
svList.antalFelSvar++;
}
}
else
{
fragaLista.get(buttonRaknare).userInput = "";
svList.antalTomtSvar++;
}
}
private void resultatToDatabas()
{
dbHelper.resultatToDatabas(svList.antalRattSvar, svList.antalFelSvar, svList.antalTomtSvar);
Intent i = new Intent(getBaseContext(),QuizResultat.class);
i.putExtra("rslist", fragaLista);
i.putExtra("sl", svList);
finish();
startActivity(i);
}
private void startCountdownTimer(long millis, final boolean isResume)
{
if (!isResume)
{
pBar.setProgress(100);
pBar.setProgressDrawable(pBar.getResources().getDrawable(R.drawable.nypbar));
}
else
{
pBar.setProgress(pBarProgress);
pBar.setProgressDrawable(pBar.getResources().getDrawable(R.drawable.nypbar));
if (pBar.getProgress() < 55 && pBar.getProgress() > 23 )
{
pBar.getProgressDrawable().setColorFilter(Color.parseColor("#FFFFB800"), PorterDuff.Mode.SRC_IN);
}
else if (pBar.getProgress() < 23)
{
pBar.getProgressDrawable().setColorFilter(Color.parseColor("#FFE71000"), PorterDuff.Mode.SRC_IN);
}
}
int callInterval = 100;
cd = new CountDownTimer(millis, callInterval)
{
public void onTick(long millisUntilFinished)
{
millisLeft = millisUntilFinished;
pBarProgress = pBar.getProgress();
int secondsRemaining = (int) millisUntilFinished / 100;
float fraction = millisUntilFinished / (float) totalMillis;
// progress bar is based on scale of 1 to 100;
pBar.setProgress((int) (fraction * 100));
cdText.setText(String.format("%2.1f", secondsRemaining / 10.0, Integer.toString(secondsRemaining)));
if (pBar.getProgress() < 55 && pBar.getProgress() > 23 )
{
pBar.getProgressDrawable().setColorFilter(Color.parseColor("#FFFFB800"), PorterDuff.Mode.SRC_IN);
}
else if (pBar.getProgress() < 23)
{
pBar.getProgressDrawable().setColorFilter(Color.parseColor("#FFE71000"), PorterDuff.Mode.SRC_IN);
}
}
public void onFinish() {
nasta.performClick();
}
}.start();
}
// Deklarera knappar, textview osv.
private void setViewElements()
{
pageNr = (TextView) findViewById(R.id.pageNumberTxt);
fraga = (TextView) findViewById(R.id.fragaTxt);
valA = (RadioButton) findViewById(R.id.valAbtn);
valB = (RadioButton) findViewById(R.id.valBbtn);
valC = (RadioButton) findViewById(R.id.valCbtn);
valD = (RadioButton) findViewById(R.id.valDbtn);
rg = (RadioGroup) findViewById(R.id.valRadioGrupp);
avsluta = (Button) findViewById(R.id.avslutaBtn);
nasta = (Button) findViewById(R.id.nastaBtn);
pBar = (ProgressBar) findViewById(R.id.progressBar);
cdText = (TextView) findViewById(R.id.counterTxt);
}
private void setButtonListeners()
{
// Nästaknapp onClick
nasta.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
cd.cancel(); // Avslutar countdowntimer
rattSvarCheck(); // Kontrollerar om svaret är rätt
if (buttonRaknare > 17)
{
nasta.setBackground(getResources().getDrawable(R.drawable.avsluta_selector));
}
if (buttonRaknare != 19) // Så länge det inte är sista frågan
{
buttonRaknare++;
rg.clearCheck(); // Tar bort check från valknapparna
startCountdownTimer(totalMillis, false); // Startar om den avslutade countdowntimer
getNastaFragaData(); // Tar nästa frågans innehåll till view
}
else if (buttonRaknare == 19)
{
resultatToDatabas(); // Sparar resultaten till databasen
}
}
});
// Avslutaknapp onClick
avsluta.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
cd.cancel(); // Pausar cooldowntimer först
visaAlertDialog(); // Visar alert dialog
}
});
}
// Visa alertDialog
private void visaAlertDialog()
{
AlertDialog.Builder adBuild = new AlertDialog.Builder(this)
.setTitle("Avsluta")
.setMessage("Vill du avsluta quizet?")
.setIcon(android.R.drawable.ic_delete)
.setPositiveButton(new String(Character.toChars(0x1F616)) + " Japp! ", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton(new String(Character.toChars(0x1F60A)) + " Nej", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
cd.cancel();
//RESUME COUNTDOWNTIMER
startCountdownTimer(millisLeft, true);
}
})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.cancel();
cd.cancel();
//RESUME COUNTDOWNTIMER
startCountdownTimer(millisLeft, true);
}
});
AlertDialog alertDialog = adBuild.create();
alertDialog.show();
}
private void checkDB()
{
try
{
dbHelper.createDataBase();
dbHelper.openDataBase();
} catch (IOException a) {
a.printStackTrace();
} catch (SQLException b) {
b.printStackTrace();
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
setContentView(R.layout.activity_quiz_page);
setViewElements();
setButtonListeners();
getNastaFragaData();
}
else
{
setContentView(R.layout.activity_quiz_page);
setViewElements();
setButtonListeners();
getNastaFragaData();
}
}
// onBackPressed metod som visar alertDialog
@Override
public void onBackPressed()
{
cd.cancel();
visaAlertDialog();
}
// onStop METHOD
@Override
protected void onStop()
{
super.onStop();
dbHelper.close();
}
}
我的测验页面布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:background="@drawable/quizpage_bg"
tools:context="com.example.onur.quiz.QuizPage">
<TextView
android:layout_width="60dp"
android:layout_height="wrap_content"
android:text="1/20"
android:id="@+id/pageNumberTxt"
android:textSize="18dp"
android:textColor="#ffab6200"
android:background="@drawable/pagenumberbg"
android:textStyle="italic|bold"
android:gravity="center"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:paddingTop="2dp"
android:paddingBottom="5dp"
android:paddingRight="3dp"
android:paddingLeft="3dp" />
<Button
android:layout_width="135dp"
android:layout_height="50dp"
android:id="@+id/nastaBtn"
android:focusable="false"
android:nestedScrollingEnabled="false"
android:background="@drawable/nasta_selector"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="15dp" />
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:id="@+id/avslutaBtn"
android:background="@drawable/exit_selector"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true" />
<RadioGroup
android:id="@+id/valRadioGrupp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="false"
android:gravity="center_vertical"
android:layout_marginTop="20dp"
android:layout_alignParentStart="false"
android:layout_below="@+id/progressBar"
android:divider="#00FFFFFF"
android:layout_above="@+id/nastaBtn"
android:layout_marginBottom="10dp"
android:background="@drawable/svarbg" >
<RadioButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="valAtxt"
android:id="@+id/valAbtn"
android:checked="false"
android:textSize="22dp"
android:layout_alignParentLeft="true"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/custom_rg_drawer"
android:paddingLeft="15dp" />
<RadioButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="valBbtn"
android:id="@+id/valBbtn"
android:checked="false"
android:textSize="22dp"
android:layout_alignLeft="@+id/nastaBtn"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/custom_rg_drawer"
android:paddingLeft="15dp" />
<RadioButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="valCbtn"
android:id="@+id/valCbtn"
android:checked="false"
android:textSize="22dp"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/custom_rg_drawer"
android:paddingLeft="15dp" />
<RadioButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="valDbtn"
android:id="@+id/valDbtn"
android:checked="false"
android:textSize="22dp"
android:layout_alignParentLeft="true"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:background="@drawable/custom_rg_drawer"
android:paddingLeft="15dp" />
</RadioGroup>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Hur många personer bor i Trollhättan?"
android:id="@+id/fragaTxt"
android:textColor="#ffc37800"
android:textSize="24dp"
android:layout_marginTop="20dp"
android:layout_below="@+id/avslutaBtn"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="false"
android:gravity="center"
android:background="@drawable/fragabg"
android:paddingLeft="10dp"
android:paddingRight="10dp" />
<ProgressBar
style="@android:style/Widget.ProgressBar.Horizontal"
android:progressDrawable = "@drawable/nypbar"
android:layout_width="290dp"
android:layout_height="10dp"
android:id="@+id/progressBar"
android:layout_marginTop="15dp"
android:layout_below="@+id/fragaTxt" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="10.00"
android:id="@+id/counterTxt"
android:layout_alignParentRight="true"
android:layout_below="@+id/fragaTxt"
android:layout_marginTop="11dp" />
</RelativeLayout>
答案 0 :(得分:1)
我不认为它与位图有很大关系,特别是如果你从Drawable资源中提取它们。延迟的来源可能是您在onCreate中发生的数据库查询,它们阻止主线程进行磁盘访问。而是使用https://developer.android.com/training/load-data-background/setup-loader.html
中描述的CursorLoader