首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在android中将秒表添加到与主线程并行运行的代码

在android中将秒表添加到与主线程并行运行的代码
EN

Stack Overflow用户
提问于 2015-04-17 07:21:20
回答 2查看 553关注 0票数 1

我正在创建一个跑步应用程序,用户可以在其中跟踪他的跑步时间和路线。在点击START时,相机应该聚焦到当前位置,计时器文本视图应该开始更新,经过的时间是秒。此外,随着用户的移动,google地图应该开始根据用户的当前位置绘制标记。

代码语言:javascript
复制
Here is the code I have written so far
package com.example.kanchan.runner7;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.*;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.android.gms.plus.Plus;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.TimeUnit;
import java.util.logging.Handler;


//1
public class HomeScreen extends FragmentActivity//,GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener
        implements View.OnClickListener,
        LocationListener {
    private  Button  buttonstart;
    private Button  buttonreset;
    private GoogleMap mMap;

    protected LocationManager locationManager;
    protected LocationListener locationListener;
    private List<LatLng> routePoints ;
    private Marker TP;
    private Marker TP1;
    private Polyline route1;

    private Location loc;

    private TextView tv;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("Kimi","onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home_screen);

        buttonstart = (Button)findViewById(R.id.button1);
        buttonstart.setOnClickListener(this);

        buttonreset = (Button)findViewById(R.id.button2);
        buttonreset.setOnClickListener(this);

        tv = (TextView)findViewById(R.id.timer);

        setUpMapIfNeeded();

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        routePoints =  new ArrayList<LatLng>();
        //route1 = new Polyline();

        // TP=  new MarkerOptions().position((new LatLng(0,0)));
        loc = new Location(LocationManager.GPS_PROVIDER);

    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_home_screen, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button1:
                buttonstartclick();
                break;



        }
    }


    private void buttonstartclick() {


        Log.d("Kimi..","kimi start button clicked");
        mMap.clear();

        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(loc.getLatitude(), loc.getLongitude()), 14));

        CameraPosition cameraPosition = new CameraPosition.Builder()
                .target(new LatLng(loc.getLatitude(), loc.getLongitude()))      // Sets the center of the map to location user
                .zoom(17)                   // Sets the zoom
                .bearing(90)                // Sets the orientation of the camera to east
                .tilt(40)                   // Sets the tilt of the camera to 30 degrees
                .build();                   // Creates a CameraPosition from the builder
        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

        stopwatch s = new stopwatch();

        s.startThread();

        while (true)
        {
            int[] curTime = s.getTime();
            Log.d("Kimi result from time", Integer.toString(curTime[2]) );
            try {
                Thread.sleep(2000);
            } catch(InterruptedException e){}

            tv.setText(Integer.toString(curTime[2]));

        }



    }

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapView))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }

    private void setUpMap() {
        mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
       /* mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
         TP = mMap.addMarker(new MarkerOptions().
                position(new LatLng(0, 0)).title("TutorialsPoint"));*/

    }



    @Override
    public void onLocationChanged(Location location) {
        if(TP1 != null)
            TP1.remove();

        Log.d("Kimi..",Double.toString(location.getLatitude()));
        Log.d("Kimi..",Double.toString(location.getLongitude()));
        loc = location;

   /*   mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                        new LatLng(location.getLatitude(), location.getLongitude()), 13));

                CameraPosition cameraPosition = new CameraPosition.Builder()
                .target(new LatLng(location.getLatitude(), location.getLongitude()))      // Sets the center of the map to location user
                .zoom(17)                   // Sets the zoom
                .bearing(90)                // Sets the orientation of the camera to east
                .tilt(40)                   // Sets the tilt of the camera to 30 degrees
                .build();                   // Creates a CameraPosition from the builder
            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
*/
        TP = mMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude()))
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.red2)));
        TP1 = mMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())));


    }



    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        Log.d("Kimi","status");
    }

    @Override
    public void onProviderEnabled(String provider) {
        Log.d("Kimi","enable");
    }

    @Override
    public void onProviderDisabled(String provider) {
        Log.d("Kimi","disable");
    }
}

如果我在buttonstartclick()中删除了秒表的部分(实际上,在我的代码中它将是incremantal.stopwatch类的扩展线程),这段代码似乎工作得很好。照相机聚焦到当前用户位置,当用户移动时,标记将放置在地图上

然而,在编写定时器代码后,相机在启动时完全停止移动。

此外,计时器文本视图不会使用while循环中的计时器值进行更新,尽管从日志中的消息可以看出,getTime()方法返回了应该向上添加的正确值

while循环似乎也没有在并行主线程中运行,因为在用户位置更改时,我看不到新的标记被放置在地图上。

有没有人可以建议一下如何在我的代码中添加秒表功能

秒表代码:

代码语言:javascript
复制
public class stopwatch extends Thread
{
    private long startTime;
    private boolean started;

    public void startThread()
    {
        this.startTime = System.currentTimeMillis();
        this.started = true;
        this.start();
    }

    public void run()
    {
        while (started)
        {
            // empty code since currentTimeMillis increases by itself
        }
    }


    public int[] getTime()
    {
        long milliTime = System.currentTimeMillis() - this.startTime;
        int[] out = new int[]{0, 0, 0, 0};
        out[0] = (int)(milliTime / 3600000      );
        out[1] = (int)(milliTime / 60000        ) % 60;
        out[2] = (int)(milliTime / 1000         ) % 60;
        out[3] = (int)(milliTime)                 % 1000;

        return out;
    }

    public void stopThread()
    {
        this.started = false;
    }
}
EN

回答 2

Stack Overflow用户

发布于 2015-04-17 07:46:03

我浏览了一下代码,但似乎你的秒表实现并不存在

但是,当您单击start按钮时,每次都会初始化int的新实例,然后调用这个不祥的start thread方法

然后进入一个在主线程上运行的无限循环,实际上是在没有if子句的情况下阻塞其他操作,顺便说一句,每次一个新的int数组用回调gettime ()填充它时,也会进行初始化。

这不应该在UI线程上处理,而应该在单独的线程中处理,可能是内部类线程,这样您就可以轻松地访问activity类的成员和方法

你的应用程序应该只是冻结,等待你的while循环结束,这就是为什么没有绘制,没有更新,等等

由于您的实现,您的文本视图将会更新,但根本不会绘制

票数 0
EN

Stack Overflow用户

发布于 2015-04-17 09:06:59

好的,开始:(我没有看到代码按钮) delTime是经过的时间oldTime是开始时间tv是文本视图的引用

代码语言:javascript
复制
public void run ()
{
oldTime=System.cur...;
while (running)
{
    setDeltaTime (); //computes the time went by.
    int hours=(int)(delTime/3600000);

    int minutes=(int)((delTime-hours*3600000)/60000);

    int seconds=(int)((delTime-hours*3600000-             minutes*6000)/1000);

    String s=""   +(hours <10?"0":"")
                          +hours
                          +":"
                          +(minutes<10?"0":"")
                          +minutes
                          +":"
                          +(second <10?"0":"")
                          +seconds;

   tv.setText (s);

   relax ()//give the thread some relaxation (sleep ());


}

}

因此,您可以将文本视图更新为00:00:00格式,并且它已脱离UI线程...这样你就不会阻止它了

(我知道你也想要mills,然后扩展这个example...and,不需要创建返回数组的方法,也不需要布尔值来检查线程是否正在运行,因为线程类对它有一个回调...isAlive ()...and在线程启动之前设置它并不好实际上在start ()时可能已经抛出了运行时异常,也许try catch也是合适的)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29687616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档