Java Android工作室编码约定&;可能的上下文错误?
现在,我正试图更加熟悉Android开发。当然,我正在使用Android Studio来完成这项工作。作为一个项目,我正在编写一个应用程序,用Java Android工作室编码约定&;可能的上下文错误?,java,android,android-studio,android-context,Java,Android,Android Studio,Android Context,现在,我正试图更加熟悉Android开发。当然,我正在使用Android Studio来完成这项工作。作为一个项目,我正在编写一个应用程序,用MediaPlayer类处理来自URL的流媒体 我得到了这个函数,并且做了我需要它做的事情。然而,我不希望我的MainActivity被可以存储在它们自己的类中的方法和变量弄得乱七八糟 关于这一点,我有几个问题: 这是常规做法吗?或者我应该将所有代码和方法都保存在它们各自的活动中,还是将它们移动到它们自己的类中,并从任何需要它们的活动中访问它们都是常规做
MediaPlayer
类处理来自URL的流媒体
我得到了这个函数,并且做了我需要它做的事情。然而,我不希望我的MainActivity被可以存储在它们自己的类中的方法和变量弄得乱七八糟
关于这一点,我有几个问题:
- 这是常规做法吗?或者我应该将所有代码和方法都保存在它们各自的活动中,还是将它们移动到它们自己的类中,并从任何需要它们的活动中访问它们都是常规做法
- 在将MediaPlayer移动到另一个类时,我在使其正确工作方面遇到问题。我读到我必须在调用该方法时给出方法
上下文。因此,我使用传递了
的对象调用了该方法,如下所示Context
main活动
,它调用我在Streaming
类中放入的方法:
public class MainActivity extends AppCompatActivity {
Streaming stream = new Streaming(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stream.updateSeekBar();
stream.onPlayClick();
stream.onDrag();
}
您可以在这里看到,我调用的所有这些方法:
public class Streaming extends AppCompatActivity {
private SeekBar musicSeek;
private TextView currentTime;
private TextView totalTime;
private ImageButton play_pause;
private Handler seekHandler = new Handler();
private MediaPlayer mp = new MediaPlayer();
Context context;
Utilities util = new Utilities();
//Default Constructor
public Streaming(){}
//Contructor
public Streaming(Context context){
this.context = context;
}
//Method to run the runnable to update the seekbar
public void updateSeekBar(){
seekHandler.postDelayed(mUpdateTimeTask, 100);
}
public void prepareStreaming() throws IOException {
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource("http://tricountynaz.net/media/audio/2017-11-08-The%20Compassion%20of%20the%20Christ.mp3");
mp.prepare();
}
public void startStreaming(){
mp.start();
}
public void pauseStreaming(){
mp.pause();
}
//Runnable to update the seekbar with the current position.
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
int totalDuration = mp.getDuration();
int currentPosition = (mp.getCurrentPosition());
//Displaying Total Duration time
totalTime = (TextView)((Activity)context).findViewById(R.id.totalTime);
totalTime.setText(util.milliSecondsToTimer(totalDuration));
// Displaying time completed playing
currentTime = (TextView)((Activity)context).findViewById(R.id.currentTime);
currentTime.setText(util.milliSecondsToTimer(currentPosition));
//Set the bars total duration, based on the song duration (converted to seconds)
musicSeek = (SeekBar)((Activity)context).findViewById(R.id.music_seek);
musicSeek.setMax(totalDuration/1000);
// Updating progress bar
musicSeek.setProgress(mp.getCurrentPosition()/1000);
// Running this thread after 100 milliseconds
seekHandler.postDelayed(this, 100);
}
};
//What happens when the user interacts with the button
public void onPlayClick (){
play_pause = (ImageButton)((Activity)context).findViewById(R.id.playButton);
play_pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
play_pause.setImageResource(R.drawable.ic_pause_name);
try {
prepareStreaming();
} catch (IOException e) {
e.printStackTrace();
}
if (mp.isPlaying()) {
pauseStreaming();
play_pause.setImageResource(R.drawable.ic_play_name);
} else {
//mediaPlayer.start();
startStreaming();
}
}
});
}
//Handles when the user interacts with the seekbar
public void onDrag(){
musicSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(b) {
//seeks to the current position of the slider when the user (b) interacts.
mp.seekTo(i*1000);
musicSeek.setProgress(i);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});}
您将注意到一个实用程序
类。目前,它只保存一个转换为秒的方法,这样我就可以更新正在播放的MP3当前进度的TextView
项
我收到的具体错误是来自onDrag
方法的NullPointerException
。我似乎不明白为什么
对不起,如果这是一个重复的,我似乎无法找到这在其他任何地方
编辑我确实稍微更改了我的onDrag
方法:
//Handles when the user interacts with the seekbar
public void onDrag(){
musicSeek = (SeekBar)((Activity)context).findViewById(R.id.music_seek);
musicSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(b) {
//seeks to the current position of the slider when the user (b) interacts.
mp.seekTo(i*1000);
musicSeek.setProgress(i);
}
}
这确实修复了nullPointerException,但现在我在日志中发现以下错误:
E/MediaPlayerNative: Attempt to call getDuration in wrong state: mPlayer=0x0, mCurrentState=0
编辑2我想我解决了我的问题。在研究我最近的错误后,我意识到我从未在MainActivity中调用我的MediaPlayer,因此没有加载任何内容,也没有流媒体。这是我找到解决方案的一部分
我的playbutton
仍然出现问题,无法正常工作,流自动启动,但这是一个小问题,我认为可以很容易地解决。然而,我仍然有兴趣知道我的代码是否有“错误”
这是常规做法吗?或者我应该将所有代码和方法都保存在它们各自的活动中,还是将它们移动到它们自己的类中,并从任何需要它们的活动中访问它们都是常规做法
一定要使用通用软件工程原理和最佳实践。设计专注于特定目的的课程。您应该看看新的体系结构组件库。这些工具允许您创建“生命周期感知”类。这些类可以负责为自己的资源处理生命周期事件,而不是用管理资源来污染活动
评论
通常,不应在活动生命周期之外初始化
活动
类的字段。当您依赖仅在生命周期的特定时间可用的资源(如视图)时,这可能会导致问题。在这种情况下,初始化与声明内联的流
对象可能不会导致任何问题。不过,最好养成将onCreate()
视为“构造函数”的习惯,并使用此方法进行所有初始化。谢谢!这正是我想知道的。因此,从现在起,我应该将所有字段(MediaPlayer、TextView等)保留在onCreate中?那通常不需要课外课吗?至少在与我的文本视图和按钮交互时?@brettsalyer我通常将视图保存在活动或片段子类中。我能想到的唯一例外是自定义列表适配器类,它也需要使用视图。我没有对MediaPlayer做过任何操作,但我可以看出在另一个类中使用它可能会有什么帮助。关键是要确保你在活动生命周期内工作。