android-新线程开启的方法自动跳到主线程

问题描述

新线程开启的方法自动跳到主线程

这是课本上的一个例子,我想跟踪线程,于是加了几处Log打印,但遇到了问题:

package com.mingrisoft;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
protected static final String TAG = "MainActivity";
private Thread thread; // 声明一个线程对象
private static MediaPlayer mp = null; // 声明一个MediaPlayer对象

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

// Log.i("AAA",String.valueOf(Thread.currentThread().getId()) );
Button button = (Button) findViewById(R.id.button1); // 获取布局管理器中添加的“开始”按钮
button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            ((Button) v).setEnabled(false); // 设置按钮不可用
            // 创建一个用于播放背景音乐的线程
            thread = new Thread(new Runnable() {

                @Override
                public void run() {
                    playBGSound(); // 播放背景音乐
                }

            });
            thread.start(); // 开启线程

// Toast.makeText(MainActivity.this, "运行的线程有:"+Thread.currentThread().getName(), Toast.LENGTH_SHORT).show();
// Log.i(TAG, Thread.currentThread().getName());
}
});
}

// 播放背景音乐
private void playBGSound() {
    Log.i(TAG, String.valueOf(Thread.currentThread().getId()));

    if (mp != null) {
        mp.release(); // 释放资源
    }
    mp = MediaPlayer.create(MainActivity.this, R.raw.dang);
    mp.start(); // 开始播放
    // 为MediaPlayer添加播放完成事件监听器
    mp.setOnCompletionListener(new OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
            try {
                Thread.sleep(2000); // 让当前线程休眠2秒钟
                 playBGSound();     // 重新播放音乐,回到主线程里
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    });
}

@Override
protected void onDestroy() {
    if (mp != null) {
        mp.stop(); // 停止播放
        mp.release(); // 释放资源
        mp = null;
    }
    if (thread != null) {
        thread = null;
    }
    super.onDestroy();
}

}
运行结果先后是 153,1,1,1,(重复是1)。不知道为什么onCompletion()方法里,在新线程休眠2s后playBGSound()会转到主线程里执行?因为我是在新线程里调用这个函数的呀,求大神解答。

时间: 2024-09-08 12:51:58

android-新线程开启的方法自动跳到主线程的相关文章

Android如何在自定义view中发送消息给主线程

问题描述 Android如何在自定义view中发送消息给主线程 求求各位大神支招,小弟在自己开发一个东西,遇到了一个小问题. ![ 图片说明](http://img.ask.csdn.net/upload/201603/15/1458054689_616589.jpg) 我在自定义view的onDraw里,当条件达到后就开启一个子线程发送消息给主线程,让主线程中的handler接收消息并执行相应的动作,可是在Log的输出下只能输出"子线程,"而没有"handlemessage

安卓,子线程获取网络图片,发消息给主线程,主线程用图片填充listview,出错

问题描述 安卓,子线程获取网络图片,发消息给主线程,主线程用图片填充listview,出错 先上logcat: 我的xml布局就是一个按钮,和一个listview,listview里就一个imageview,按下按钮开始从网络获取图片,然后发消息到主线程,然后listview就填充数据.xml代码就不贴了. 以下是mainactivity public class MainActivity extends AppCompatActivity implements View.OnClickList

自动登录 阻塞主线程

问题描述 如果设置了自动登录, 在刚启动程序时即 走didFinishLaunchingWithOptions 这个方法的时候 ,自动登录就会会阻碍主线程.,这个如果在网络条件不好的情况下,用户体验时极差的.请问 有什么解决方法.在哪里可以把自动登录的方法放在子线程中? 解决方案 自动登陆在初始化之前调用就行

详解Android中Handler的使用方法_Android

在Android开发中,我们经常会遇到这样一种情况:在UI界面上进行某项操作后要执行一段很耗时的代码,比如我们在界面上点击了一个"下载"按钮,那么我们需要执行网络请求,这是一个耗时操作,因为不知道什么时候才能完成.为了保证不影响UI线程,所以我们会创建一个新的线程去执行我们的耗时的代码.当我们的耗时操作完成时,我们需要更新UI界面以告知用户操作完成了.所以我们可能会写出如下的代码: package ispring.com.testhandler; import android.app.

理解iOS多线程应用的开发以及线程的创建方法_IOS

一.进程和线程1.什么是进程   进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过"活动监视器"可以查看Mac系统中所开启的进程   2.什么是线程 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程) 线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 比如使用酷狗播放音乐.使用迅雷下载电影,都需要在线程中执行 3.线程的串行   1个线程

安卓用线程怎么实现viewpager自动切换

问题描述 安卓用线程怎么实现viewpager自动切换 安卓用线程怎么实现viewpager自动切换. 解决方案 你干嘛用线程,它里面实现好了呀,在View尽量不要使用线程,没必要,因为有invalidte呀! 解决方案二: 自动切换有两种,一种直接更换图片,一种是有切换图片体现,就是切换过程图片会滑动.前者简单,直接重写ViewPager,里面构造方法启动定时任务: 后者要自己自定义布局,自己斟酌吧.这只是个大的方向 解决方案三: thread也能用来切换viewpager? 解决方案四: 开

Java创建线程安全的方法

原文链接 译者:秦建平 校对:方腾飞 首先来看一个问题: 下面这个方法是线程安全的吗?如何才能让这个方法变成线程安全的? 1 public class MyCount { 2   private static int counter = 0; 3   4   public static int getCount(){ 5     return counter++; 6   } 7 } 首先,这个方法不是线程安全的,因为counter++操作不是一个原子性的操作,也就意味着counter++操作包

c++中如何将子线程的参数传回主线程

问题描述 c++中如何将子线程的参数传回主线程 1C DWORD WINAPI threadFunction(LPVOID pArg) //返回值进程id(dword类型) 参数类型 LPVOID{ tNum myNum = *((tNum *)pArg); //将参数转化成int型 EnterCriticalSection(&gCS); // 进入临界区 myNum.string_back = FuzzyHash(myNum.string_in); LeaveCriticalSection(&a

在线程的run方法中执行页面跳转

问题描述 在线程的run方法中执行页面跳转 在做Android程序开发时,想在线程中休眠一段时间之后直接跳转到其他activity中,为什么不能再run方法中直接写. 解决方案 如果 是主线程的话那是肯定不行的直接程序崩溃,开启子线程的话是可以在run()里面写的.你可以用handle.postDlay()这样写,也可以用timeTask.schem()来