Получение Android-активности для запуска неактивного кода - PullRequest
1 голос
/ 27 июля 2011

У меня есть приложение для Android, которое в основном отображает точки на карте. Эти карты определяются из совершенно другого класса. Первоначально я написал этот класс как собственную программу (он читает файл CSV, выбирает точки и возвращает их долготу и широту в массиве).

Итак, я добавил этот класс в свою программу Android App. Я хочу, чтобы приложение в какой-то момент вызывало метод класса, который будет генерировать массив, возвращал его и использовал этот новый массив для построения точек на карте. Что касается захвата массива и определения каждой их широты и долготы, я могу это сделать.

Однако, когда в основном классе моего приложения для Android я заявляю:

String[][] bump = ReadCsv.getArray(fileToUse);

, моя программа принудительно закроется. (ReadCsv - это имя класса, который я поместил в программу - getArray - единственный метод в классе, и он возвращает массив [] []).

Кто-нибудь думает, что они видят, в чем моя проблема? Может быть, возможно альтернативное решение?

LogCat это: 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): ИСКЛЮЧИТЕЛЬНОЕ ИСКЛЮЧЕНИЕ: основное 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): java.lang.RuntimeException: невозможно запустить действие ComponentInfo {net.learn2develop.GoogleMaps / net.learn2develop.GoogleMaps.MapsActivity}: java.lang.NullPointerException 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2663) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2679) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на android.app.ActivityThread.access $ 2300 (ActivityThread.java:125) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на android.app.ActivityThread $ H.handleMessage (ActivityThread.java:2033) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на android.os.Handler.dispatchMessage (Handler.java:99) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на android.os.Looper.loop (Looper.java:123) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на android.app.ActivityThread.main (ActivityThread.java:4627) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на java.lang.reflect.Method.invokeNative (собственный метод) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): в java.lang.reflect.Method.invoke (Method.java:521) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:858) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:616) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): в dalvik.system.NativeStart.main (собственный метод) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): вызвано: java.lang.NullPointerException 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): по адресу net.learn2develop.GoogleMaps.MapsActivity.onCreate (MapsActivity.java:86) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1047) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): на android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2627) 07-27 15: 19: 25.105: ОШИБКА / AndroidRuntime (12214): ... еще 11

И мой код:

package net.learn2develop.GoogleMaps;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.List;
import java.util.StringTokenizer;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.MapView.LayoutParams;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;


public class MapsActivity extends MapActivity 
{    
MapView mapView; 
MapController mc;
GeoPoint p;
GeoPoint p2;
GeoPoint p99;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mapView = (MapView) findViewById(R.id.mapView);
    LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);  
    @SuppressWarnings("deprecation")
    View zoomView = mapView.getZoomControls(); 

    mapView.setSatellite(true);

    zoomLayout.addView(zoomView, 
        new LinearLayout.LayoutParams(
            LayoutParams.WRAP_CONTENT, 
            LayoutParams.WRAP_CONTENT)); 
    mapView.displayZoomControls(true);

    mc = mapView.getController();
    String coordinates[] = {"42.30936432", "-71.12162781"};
    double lat = Double.parseDouble(coordinates[0]);
    double lng = Double.parseDouble(coordinates[1]);

    p = new GeoPoint(
            (int) (lat * 1E6), 
            (int) (lng * 1E6));

    mc.animateTo(p);
    mc.setZoom(8); 

    //---Add a location marker---
    MapOverlay mapOverlay = new MapOverlay();
    List<Overlay> listOfOverlays = mapView.getOverlays();
    //listOfOverlays.clear();
    listOfOverlays.add(mapOverlay); 

    // -- my own point ---
    String coordinates2[] = {"42.20", "-71.20"};
    double lat2 = Double.parseDouble(coordinates2[0]);
    double lng2 = Double.parseDouble(coordinates2[1]);
    p2 = new GeoPoint(
            (int) (lat2 * 1E6),
            (int) (lng2 * 1E6));
    MapOverlay mapOverlay2 = new MapOverlay();
    List<Overlay> listOfOverlays2 = mapView.getOverlays();
    listOfOverlays2.add(mapOverlay2);

    // Add points from ReadCsv.java
    File fileToUse = new File("/Users/csrobot/Desktop/Training4.csv");
    String[][] bump = ReadCsv.getArray(fileToUse);
    for(int i = 0; i < bump.length; i++) {
        String coordinates99[] = {bump[i][0], bump[i][1]};
        double lat99 = Double.parseDouble(coordinates99[0]);
        double lng99 = Double.parseDouble(coordinates99[1]);
        p99 = new GeoPoint(
                (int) (lat99 * 1E6),
                (int) (lng99 * 1E6));
        MapOverlay mapOverlay99 = new MapOverlay();
        List<Overlay> listOfOverlays99 = mapView.getOverlays();
        listOfOverlays99.add(mapOverlay99);
    } 

    mapView.invalidate();
}

class MapOverlay extends com.google.android.maps.Overlay
{
    @Override
    public boolean draw(Canvas canvas, MapView mapView, 
    boolean shadow, long when) 
    {
        super.draw(canvas, mapView, shadow);                   

        //---translate the GeoPoint to screen pixels---
        Point screenPts = new Point();
        mapView.getProjection().toPixels(p, screenPts);

        //---add the marker---
        Bitmap bmp = BitmapFactory.decodeResource(
                getResources(), R.drawable.redpin);            
        canvas.drawBitmap(bmp, screenPts.x, screenPts.y-44, null);         


        // --make my own point---
        Point screenPts2 = new Point();
        mapView.getProjection().toPixels(p2, screenPts2);
        Bitmap bmp2 = BitmapFactory.decodeResource(
                getResources(), R.drawable.redpin);
        canvas.drawBitmap(bmp2, screenPts2.x, screenPts2.y-44, null);


        return true;
    }
} 

static class ReadCsv {

    public static String[][] getArray(File file) {

        try {
                   //
                   // Code That I know Works is Here
                   //
            return arrayOfBumps;

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch(Exception e) {
                  // System.out.println("The following error occurred "+e);
        }
        return null;

    }
}

@Override
protected boolean isRouteDisplayed() {
    return false;
}
}

РЕДАКТИРОВАТЬ: Для Рави Бхатт

private class MapPoint extends AsyncTask <String[][], String, String> {

    @Override  
    protected String doInBackground(String[][]... <<What goes here...? >>) {

    String << what am i making to return? >> = null;
    try {
        InputStream is = getAssets().open("Training4.csv");
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        bump = getArray(reader);
        if(bump == null){
                setContentView(R.layout.deleteme);
            } else {
                for(int i = 0; i < bump.length; i++) {
                    String coordinates99[] = {bump[i][0], bump[i][1]};
                    double lat99 = Double.parseDouble(coordinates99[0]);
                    double lng99 = Double.parseDouble(coordinates99[1]);
                    p99 = new GeoPoint(
                        (int) (lat99 * 1E6),
                        (int) (lng99 * 1E6));
                    MapOverlay mapOverlay99 = new MapOverlay();
                    List<Overlay> listOfOverlays99 = mapView.getOverlays();
                    listOfOverlays99.add(mapOverlay99);
                } 
            }
    } catch (IOException e) {
        e.printStackTrace();
    }

    return << do I really need to return something? if so, what? >>;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    mapView.refreshDrawableState();

}

}

Ответы [ 3 ]

2 голосов
/ 27 июля 2011

Лучшее решение для ваших нужд - AsyncTask. используйте эту ссылку http://developer.android.com/reference/android/os/AsyncTask.html

Вы можете передавать параметры в doInBackground () методах. params может быть списком широты и долготы.

- сделать геолокации

- создать оверлейтем

- добавить его в подробное наложение

onPostExectute () метод делает следующее.

- добавить его в mapoverlay, т.е. список оверлеев. - после этого вы можете использовать метод refreshdrawablestate ().

для наложения этого наложения из класса неактивности вы можете использовать ссылку или контекст mapactivity и использовать его для добавления наложения.

РЕДАКТИРОВАТЬ:

например, рассмотрим пример просмотра карты по ссылке http://developer.android.com/resources/tutorials/views/hello-mapview.html

При использовании AsncTask, поскольку у вас есть массив координат, передайте этот массив в AsyncTask в качестве параметров, подобных AsyncTask.

затем doInBackGround () метод использования doInBackGroud , поскольку у вас есть строковый массив. Поместите это для логики цикла для получения координат и Geopoint в методе doInBackGround.

- добавить каждый элемент оверлея, который вы получаете из координаты, в itemizedOverlay (по ссылке в Привет карте).

- В методе onPostExecute () добавьте это наложение в список на карте и используйте mapview.refreshdrawablestate (). вы можете использовать onPostExecute с объявлением, например onPostExecute (недействительный результат)

Сделайте вышеуказанный шаг с пониманием и его СДЕЛАНО !!! :)

0 голосов
/ 27 июля 2011

Используете ли вы его из источника или файла Jar? Если вы используете его как файл Jar, он может умереть, потому что ваша программа использует API, недоступный для Android. Другой вариант может касаться аргов. Я бы попробовал передать ReadCSV.main (новая строка [] {}).

Я вижу исключение java.lang.NullPointerException, но просматривать logcat сложно из-за форматирования. Но что-то внутри ReadCSV бросает NPE. Я бы посоветовал пройти через ReadCSV с помощью отладчика или найти номер строки, которая перебрасывает этот NPE. На самом деле нашел это:

net.learn2develop.GoogleMaps.MapsActivity.onCreate (MapsActivity.java:81)

Так что в строке 81 в MapsActivity есть проблема. Похоже, что ReadCSV.main () еще не достигнут.

Я бы также последовал предложению сделать это внутри AsyncTask. Даже я бы хотел выделить весь ваш код в правильный метод, который вы можете напрямую вызывать и возвращать Array напрямую, потому что ReadCSV.main () является пустым типом возврата. То, что он производит, должно быть файлом или чем-то таким, чтобы вы могли получить эти данные. Вместо этого просто верните простой массив. Что-то вроде:

public List<Row> readCSV( File f ) {
}

Это то, что вы можете сделать, чтобы облегчить себе это дело.

0 голосов
/ 27 июля 2011

Может быть много причин, по которым вы видите близкую силу. Вы пробовали войти в основной метод и посмотреть, где он падает? Возможно, вы используете параметр для чего-то, что вызывает сбой при передаче значения NULL. то есть вы передавали имя файла для использования в автономном приложении?

Этот тип операции, как правило, не выполняется внутри действия, так как это может сделать пользовательский интерфейс вашего приложения излишним. Я бы расследовал IntentService и вызвал бы ваш код из него. Затем вы можете вызывать IntentService в любое время из своего пользовательского интерфейса.

...