gpt4 book ai didi

java - ToneGenerator 会严重降低应用程序的速度

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:38:01 25 4
gpt4 key购买 nike

我正在编写一个计时器应用程序,提供服务并每 30 秒发出一次蜂鸣声(实际上有一个下拉菜单可以更改时间)。

然而,当我让应用程序发出哔哔声时,哔哔声会持续很长时间并卡住应用程序,最终(大约 5 秒后)它完成,然后计时器 catch 。为什么会这样?我该如何解决?这是我的代码:

主要 Activity .java:

package com.example.servicetimer;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.ToneGenerator;
import android.net.Uri;
import android.os.Vibrator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
private Button startButton;
private Button pauseButton;
private Button resetButton;

private TextView timerValue;
private TextView timerValueMils;

private long miliTime;

private int beepTime = 0;

private boolean running = false;
private boolean beep = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
miliTime = 0L;
timerValue = (TextView) findViewById(R.id.timerValue);
timerValueMils = (TextView) findViewById(R.id.timerValueMils);

registerReceiver(uiUpdated, new IntentFilter("TIMER_UPDATED"));

startButton = (Button) findViewById(R.id.startButton);

startButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {
if (running){
return;
}
Intent i = new Intent(MainActivity.this,LocalService.class);
i.putExtra("timer",miliTime);

startService(i);
running = true;
resetButton.setVisibility(View.GONE);
}
});

pauseButton = (Button) findViewById(R.id.pauseButton);

pauseButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {
if(!running){
return;
}
running = false;
stopService(new Intent(MainActivity.this, LocalService.class));
resetButton.setVisibility(View.VISIBLE);
}
});

resetButton = (Button) findViewById(R.id.resetButton);

resetButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {
stopService(new Intent(MainActivity.this, LocalService.class));
running = false;
miliTime = 0L;
((TextView) findViewById(R.id.timerValue)).setText(R.string.timerVal);
((TextView) findViewById(R.id.timerValueMils)).setText(R.string.timerValMils);
beep = false;
}
});

Spinner dropdown = (Spinner)findViewById(R.id.spinner1);
ArrayAdapter<CharSequence> adapter = ArrayAdapter
.createFromResource(this, R.array.times,
android.R.layout.simple_spinner_item);
dropdown.setAdapter(adapter);
dropdown.setSelection(1);

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

dropdown.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
// On selecting a spinner item
String label = parent.getItemAtPosition(position).toString();
beepTime = Integer.parseInt(label);
}

public void onNothingSelected(AdapterView<?> parent) {
beepTime = 30;
}
});

}

private BroadcastReceiver uiUpdated = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
//This is the part where I get the timer value from the service and I update it every second, because I send the data from the service every second. The coundtdownTimer is a MenuItem
miliTime = intent.getExtras().getLong("timer");
long secs = miliTime/1000;
int mins = (int) (secs/60);
secs = secs % 60;
if (secs > 0)
beep = true;
if ((secs % beepTime == 0) && beep)
beep();
int millis = (int) (miliTime % 1000);

timerValue.setText("" + mins + " "
+ String.format("%02d", secs));
timerValueMils.setText(String.format("%02d", millis/10));


}

public void beep(){
/*try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}*/

final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
tg.startTone(ToneGenerator.TONE_PROP_BEEP,100);
tg.stopTone();
tg.release();
/*ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200);*/
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
v.vibrate(500);
}
};


}

本地服务.java:

package com.example.servicetimer;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

import java.util.Timer;
import java.util.TimerTask;

public class LocalService extends Service
{
private static Timer timer;
private Context ctx;
private static long miliTime = 0;

public IBinder onBind(Intent arg0)
{
return null;
}

public void onCreate()
{
timer = new Timer();
super.onCreate();
ctx = this;
miliTime = 0;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
miliTime = intent.getExtras().getLong("timer");
timer = new Timer();
timer.scheduleAtFixedRate(new mainTask(), 0, 10);
return START_STICKY;
}

private class mainTask extends TimerTask
{
public void run()
{
miliTime += 10;
Intent i = new Intent("TIMER_UPDATED");
i.putExtra("timer",miliTime);

sendBroadcast(i);
}
}

public void onDestroy() {
super.onDestroy();
timer.cancel();
miliTime = 0L;
}
}

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="@drawable/silver"
android:layout_height="match_parent" >

<TextView
android:id="@+id/timerValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/pauseButton"
android:layout_centerHorizontal="true"
android:layout_marginBottom="37dp"
android:textSize="40sp"
android:textColor="#000000"
android:text="@string/timerVal" />

<TextView
android:id="@+id/timerValueMils"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/timerValue"
android:layout_toEndOf="@+id/timerValue"
android:layout_above="@+id/pauseButton"
android:layout_centerHorizontal="true"
android:layout_marginBottom="45dp"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:textSize="20sp"
android:textColor="#000000"
android:text="@string/timerValMils" />

<Button
android:id="@+id/startButton"
android:layout_width="90dp"
android:layout_height="45dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginLeft="38dp"
android:layout_marginStart="38dp"
android:text="@string/startButtonLabel" />

<Button
android:id="@+id/pauseButton"
android:layout_width="90dp"
android:layout_height="45dp"
android:layout_alignBaseline="@+id/startButton"
android:layout_alignBottom="@+id/startButton"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="38dp"
android:layout_marginEnd="38dp"
android:text="@string/pauseButtonLabel" />

<RelativeLayout android:id="@+id/dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/pauseButton"
android:layout_marginTop="37dp">

<TextView
android:id="@+id/secondsToBeep"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="37dp"
android:layout_marginStart="37dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:textSize="30sp"
android:textColor="#000000"
android:text="@string/beeps" />

<Spinner
android:id="@+id/spinner1"
android:dropDownWidth="80dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:drawable/btn_dropdown"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginEnd="40dp"
android:layout_marginRight="40dp"
android:layout_marginLeft="40dp"
android:layout_marginStart="40dp"
android:spinnerMode="dropdown"
android:popupBackground="@drawable/silver"/>
</RelativeLayout>

<Button
android:id="@+id/resetButton"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_below="@id/dropdown"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="50dp"
android:text="@string/resetButtonLabel"
android:visibility="gone"/>

</RelativeLayout>

如有必要,我可以添加我的 AndroidManifest。在 AndroidStudio 上进行调试时,它会给我以下信息:

I/Choreographer: Skipped 35 frames!  The application may be doing too much work on its main thread.
I/Choreographer: Skipped 175 frames! The application may be doing too much work on its main thread.
I/Choreographer: Skipped 44 frames! The application may be doing too much work on its main thread.

我应该在服务中发出哔哔声还是什么?

我要补充一点,我确信这是来自 ToneGenerator,我已经注释掉所有声音部分,只留下振动器,当它运行时没有问题。但是 ToneGeneratorRingtone 都导致了这个问题

最佳答案

我实际上回答了我自己的问题,问题(在这种情况下)是我调用beep()方式太频繁了。

我的代码是:

if ((secs % beepTime == 0) && beep)
beep();

但我真正想要的是以毫秒为单位进行计算。我导致调用 beep() 100 次(代码每 10 毫秒更新一次)的方式。

关于java - ToneGenerator 会严重降低应用程序的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41906030/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com