1

如何从另一个类获取/刷新位置取消线程。我可以从同一个类中取消一个线程。但我无法跨班级做到这一点。声明 GPSThread 静态并没有帮助。任何人都可以请指导吗?

第一类:

public class GPSListener {
    /* Other instantiation code */
    Dialog busyDialog1 = new Dialog("Refreshing Location...",
                                    new String [] { "Cancel" },
                                    new int [] { Dialog.CANCEL},
                                    Dialog.CANCEL,
                                    Bitmap.getPredefinedBitmap(Bitmap.HOURGLASS))
    {
        public void fieldChanged(Field field1, int context1)
        {
            GPSHandler.requestStop();
            busyDialog1.cancel();
        }
    };

    public String refreshCoordinates() {
        String test = "nothing";
        if (GPSHandler.isStopRequested())
        {
            GPSHandler.stopRequested = false;
            return null;
        }
        GPSHandler.getInstance().setListener(this);
        GPSHandler.getInstance().requestLocationUpdates();
        if (GPSHandler.isStopRequested())
        {
            GPSHandler.stopRequested = false;
            return null;
        }
        busyDialog1.setEscapeEnabled(false);
        busyDialog1.show();
        return test;
    }

    public void onLocationReceived(Coordinates location) {
        lblLatitude.setText(Double.toString(location.getLatitude()));
        lblLongitude.setText(Double.toString(location.getLongitude()));
        busyDialog1.cancel();
    }
}

第 2 类:

public class GPSHandler {
    private GPSThread _gpsThread;
    private Coordinates _location;
    private boolean _gotLocation;
    private GPSListener _listener;

    /** this class will be a Singleton, as the device only has one GPS system */
    private static GPSHandler _instance;

    /** @return the Singleton instance of the GPSHandler */
    public static GPSHandler getInstance() {
        if (_instance == null) {
            _instance = new GPSHandler();
        }
        return _instance;
    }

    public static boolean stopRequested = false;
    public synchronized static void requestStop() {
        stopRequested = true;
    }
    public synchronized static boolean isStopRequested() {
        return stopRequested;
    }

    /** not publicly accessible ... use getInstance() */
    private GPSHandler() {
    }

    /** call this to trigger a new location fix */
    public void requestLocationUpdates() {
        if (_gpsThread == null || !_gpsThread.isAlive()) {
            _gpsThread = new GPSThread();
            _gpsThread.start();
        }
    }

    public void setListener(GPSListener listener) {
        // only supports one listener this way
        _listener = listener;
    }

    private void setLocation(final Coordinates value) {
        _location = value;
        if (value.getLatitude() != 0.0 || value.getLongitude() != 0.0) {
            _gotLocation = true;
            if (_listener != null) {
                // this assumes listeners are UI listeners, and want callbacks on the UI thread:
                UiApplication.getUiApplication().invokeLater(new Runnable() {
                    public void run() {
                        _listener.onLocationReceived(value);
                    }
                });
            }
        }
    }

    private class GPSThread extends Thread {
        private void getLocationFromGoogle() {
            try {
                int cellID = GPRSInfo.getCellInfo().getCellId();
                int lac = GPRSInfo.getCellInfo().getLAC();
                String urlString2 = "http://www.google.com/glm/mmap";

                // Open a connection to Google Maps API
                ConnectionFactory connFact = new ConnectionFactory();
                ConnectionDescriptor connDesc;
                connDesc = connFact.getConnection(urlString2);
                HttpConnection httpConn2;
                httpConn2 = (HttpConnection)connDesc.getConnection();
                httpConn2.setRequestMethod("POST");

                // Write some custom data to Google Maps API
                OutputStream outputStream2 = httpConn2.openOutputStream();//getOutputStream();
                writeDataGoogleMaps(outputStream2, cellID, lac);

                // Get the response
                InputStream inputStream2 = httpConn2.openInputStream();//getInputStream();
                DataInputStream dataInputStream2 = new DataInputStream(inputStream2);

                // Interpret the response obtained
                dataInputStream2.readShort();
                dataInputStream2.readByte();
                final int code = dataInputStream2.readInt();

                UiApplication.getUiApplication().invokeLater(new Runnable() {
                    public void run() {
                        Dialog.alert(code + "");
                    }
                });
                if (code == 0) {
                    final double latitude = dataInputStream2.readInt() / 1000000D;
                    final double longitude = dataInputStream2.readInt() / 1000000D;
                    setLocation(new Coordinates(latitude, longitude, 0.0f));

                    UiApplication.getUiApplication().invokeLater(new Runnable() {
                        public void run() {
                            Dialog.alert(latitude+"-----"+longitude);
                        }
                    });

                    dataInputStream2.readInt();
                    dataInputStream2.readInt();
                    dataInputStream2.readUTF();
                } else {
                    System.out.println("Error obtaining Cell Id ");
                }
                outputStream2.close();
                inputStream2.close();
            } catch (Exception e) {
                System.out.println("Error: " + e.getMessage());
            }
        }

        private void tryGetLocationFromDevice() {
            _gotLocation = false;
            try {
                Criteria myCriteria = new Criteria();
                myCriteria.setCostAllowed(false);
                LocationProvider myLocationProvider = LocationProvider.getInstance(myCriteria);
                try {
                    Location myLocation = myLocationProvider.getLocation(300);
                    setLocation(myLocation.getQualifiedCoordinates());
                } catch ( InterruptedException iex ) {
                    System.out.println(iex.getMessage());
                } catch ( LocationException lex ) {
                    System.out.println(lex.getMessage());
                }
            } catch ( LocationException lex ) {
                System.out.println(lex.getMessage());
            }
            if (!_gotLocation) {
                getLocationFromGoogle();
            }
        }

        public void run() {
            int bbMapsHandle = CodeModuleManager.getModuleHandle("net_rim_bb_lbs"); // OS 4.5 - 6.0
            int bbMapsHandle60 = CodeModuleManager.getModuleHandle("net_rim_bb_maps"); // OS 6.0
            if (bbMapsHandle > 0 || bbMapsHandle60 > 0) {
                tryGetLocationFromDevice();
            } else {
                getLocationFromGoogle();
            }
        }
    }

    private void writeDataGoogleMaps(OutputStream out, int cellID, int lac) throws IOException {
        DataOutputStream dataOutputStream = new DataOutputStream(out);
        dataOutputStream.writeShort(21);
        dataOutputStream.writeLong(0);
        dataOutputStream.writeUTF("en");
        dataOutputStream.writeUTF("Android");
        dataOutputStream.writeUTF("1.0");
        dataOutputStream.writeUTF("Web");
        dataOutputStream.writeByte(27);
        dataOutputStream.writeInt(0);
        dataOutputStream.writeInt(0);
        dataOutputStream.writeInt(3);
        dataOutputStream.writeUTF("");
        dataOutputStream.writeInt(cellID);
        dataOutputStream.writeInt(lac);
        dataOutputStream.writeInt(0);
        dataOutputStream.writeInt(0);
        dataOutputStream.writeInt(0);
        dataOutputStream.writeInt(0);
        dataOutputStream.flush();
    }
} 
4

2 回答 2

2

您的对象当前被声明GPSThread为. 如果您想从范围之外停止执行(或确实对其执行任何操作),则需要将其标记为. 您还需要提供一些公共机制(例如方法)来取消线程执行。privateGPSHandlerGPSHandlerpublicstop()

最常见的方法是boolean在你的线程(例如)中有一个标志 shouldStop,在你的主执行循环内部检查run()它是否应该停止。当stop()方法被调用时shouldStop设置为true并且你的线程将停止。

这是一个很好的例子:如何在 Java 中停止线程?

于 2012-08-16T11:10:31.743 回答
1

您应该进行两组更改。

更改停止请求标志

首先,请记住封装在面向对象语言中是一件好事。的isStopRequested()方法或stopRequested变量GPSHandler不应在该类之外使用。您的 UIGPSListener不应尝试使用其中任何一个。我会改变你GPSHandler使用这个:

private static boolean stopRequested = false;

public synchronized static void requestStop() {
   stopRequested = true;
}

private synchronized static boolean isStopRequested() {
   return stopRequested;
}

只是requestStop()应该public。看起来您stopRequested已公开以允许GPSListener重置它。如果需要重置,让拥有该变量的类进行重置。例如,在GPSHandler

   /** call this to trigger a new location fix */
   public void requestLocationUpdates() {
       if (_gpsThread == null || !_gpsThread.isAlive()) {
          // reset this stop flag:
          stopRequested = false;
          _gpsThread = new GPSThread();
          _gpsThread.start(); 
       }
   }

requestLocationUpdates()确实是启动线程的方法,所以它应该是stopRequested重置为false.

此外,您不应该stopRequested public允许其他类使用它的另一个原因是这通常不是线程安全的。stopRequested使用requestStop()and方法进行包装的原因之一isStopRequested()是添加线程安全性。有很多方法可以做到这一点,但这两种方法通过用synchronized关键字标记来实现线程安全。

更改检查标志的方式/位置

进行这些修复后,您需要更改检查是否已请求停止的位置。你真的不想检查isStopRequested()方法refreshCoordinates()。该方法几乎不涉及任何工作。即使它启动了获取位置修复的过程,也只是启动了一个线程,但获取位置的实际工作是在后台线程(您的GPSThread)上完成的。如果requestStop()被调用,它不太可能在中间被调用refreshCoordinates(),所以这不是你应该检查它的地方。

isStopRequested()在类GPSHandler的方法tryGetLocationFromDevice()getLocationFromGoogle(). 这些是执行缓慢处理的方法。这些是你可能想在中间打断的那些。所以,像这样:

     private void getLocationFromGoogle() {
         try { 
            int cellID = GPRSInfo.getCellInfo().getCellId(); 
            int lac = GPRSInfo.getCellInfo().getLAC(); 

            String urlString2 = "http://www.google.com/glm/mmap"; 

            if (isStopRequested()) return;

            // Open a connection to Google Maps API  
            ConnectionFactory connFact = new ConnectionFactory(); 
            ConnectionDescriptor connDesc; 
            connDesc = connFact.getConnection(urlString2); 

            HttpConnection httpConn2; 
            httpConn2 = (HttpConnection)connDesc.getConnection(); 
            httpConn2.setRequestMethod("POST"); 

            // Write some custom data to Google Maps API  
            OutputStream outputStream2 = httpConn2.openOutputStream();//getOutputStream(); 
            writeDataGoogleMaps(outputStream2, cellID, lac); 

            if (isStopRequested()) return;

            // Get the response   
            InputStream inputStream2 = httpConn2.openInputStream();//getInputStream(); 
            DataInputStream dataInputStream2 = new DataInputStream(inputStream2); 

            // Interpret the response obtained  
            dataInputStream2.readShort(); 
            dataInputStream2.readByte(); 

            if (isStopRequested()) return;

            final int code = dataInputStream2.readInt(); 
            UiApplication.getUiApplication().invokeLater(new Runnable() {
               public void run() {
                  Dialog.alert(code + "");   
               }
            });                        

在 中tryGetLocationFromDevice(),您可以这样做(确保在下面添加成员变量和新方法):

      private LocationProvider _locationProvider;  // must be a member variable!

      public void requestStop() {
         if (_locationProvider != null) {
             // this will interrupt the _locationProvider.getLocation(300) call
             _locationProvider.reset();
         }
      }

      private void tryGetLocationFromDevice() {
         _gotLocation = false;
         try {
            Criteria myCriteria = new Criteria(); 
            myCriteria.setCostAllowed(false); 
            _locationProvider = LocationProvider.getInstance(myCriteria); 

            try { 
               Location myLocation = _locationProvider.getLocation(300); 
               setLocation(myLocation.getQualifiedCoordinates()); 
            } catch ( InterruptedException iex ) { 
               // this may be caught if stop requested!!!!
               System.out.println(iex.getMessage());
            } catch ( LocationException lex ) { 
               System.out.println(lex.getMessage());
            } 
         } catch ( LocationException lex ) { 
            System.out.println(lex.getMessage());
         }

         if (!_gotLocation && !isStopRequested()) { 
            getLocationFromGoogle();
         } 
      }

GPSThread.requestStop()然后,从外部 方法调用该GPSHandler.requestStop()方法:

public synchronized static void requestStop() {
   stopRequested = true;
   if (_gpsThread != null) {
       _gpsThread.requestStop();
   }
}
于 2012-08-24T09:51:51.367 回答