Search code examples
androidarraysandroid-intentbroadcastreceiver

Android - Passing long array via broadcast intent


I wrote a little android program, there is a main activity with a broadcast listener, and i create another thread. The thread searches for prime numbers, and loading them into a long arraylist, and after every 3 seconds, sends the filled array to the main activity via broadcast. Everythings ok, until i'm trying to get the long array extra from the intent. It causes every time a nullpointerexception. I tried with a string arraylist, it worked, but i am curious because the intent has an "getlongarrayextra" method.

Here is my code:

public class MainActivity extends Activity {

public static String BROADCAST_THREAD_KEY = "broadcast_key";
public static String EXTRAARRAYID = "primes";
private static long MAXNUM = 2000000;
private PrimeCalculatorThread thread;
TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textView = (TextView) findViewById(R.id.numberstext);
}

private BroadcastReceiver receiver = new BroadcastReceiver() {
    public void onReceive(android.content.Context context,
            android.content.Intent intent) {
        String origitext = textView.getText().toString();
        long[] primes = intent.getExtras().getLongArray(EXTRAARRAYID);
        Log.d("ASD", "broadcast received" + primes.toString());
        StringBuilder builder = new StringBuilder();
        if (primes != null) {
            for (long prime : primes) {
                builder.append(prime + " - ");
            }
            textView.setText(origitext + "\n" + builder.toString());
        }

    };
};

@Override
protected void onResume() {
    Log.d("ASD", "ONRESUME");
    initReceiverAndStartThread();
    super.onResume();
}

private void initReceiverAndStartThread() {
    IntentFilter filter = new IntentFilter(BROADCAST_THREAD_KEY);
    registerReceiver(receiver, filter);
    thread = new PrimeCalculatorThread(getBaseContext(), MAXNUM);
    thread.start();
    Log.d("ASD", "THREAD STARTED");
}

and the second thread:

public class PrimeCalculatorThread extends Thread {

private Context context;
private long maxnum;
List<Long> primes;
boolean isrunning;

public void setIsrunning(boolean isrunning) {
    this.isrunning = isrunning;
}

private long counter = 0;
private long DELAYBETWEENBROADCAST = 3000;

public PrimeCalculatorThread(Context c, long maxnum) {
    this.context = c;
    this.maxnum = maxnum;
    primes = new ArrayList<Long>();
}

@Override
public void run() {
    long startTime = System.currentTimeMillis();
    long estimatedTime;
    isrunning = true;
    for (long i = 0; i < maxnum; i++) {
        Log.d("ASD", Boolean.toString(isrunning));
        if (!isrunning)
            break;
        Log.d("ASD", i + "");
        estimatedTime = System.currentTimeMillis() - startTime;
        if (isPrime(i)) {
            primes.add(i);
            Log.d("ASD", i + "is a prime");
        } else {
            Log.d("ASD", i + "is not a prime");
        }
        if (estimatedTime > counter * DELAYBETWEENBROADCAST
                + DELAYBETWEENBROADCAST) { // elapsed another period
            Log.d("ASD", primes.toString() + " will be sending.");
            sendBroadCast();
            primes.clear();
            counter++;
        }
        try {                       //for debug purposes
            Thread.sleep(250);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

private void sendBroadCast() {
    Intent intent = new Intent(MainActivity.BROADCAST_THREAD_KEY);
    intent.putExtra(MainActivity.EXTRAARRAYID, primes.toArray());
    context.sendBroadcast(intent);
    Log.d("ASD", "BROADCAST SENT" + primes.toString());
}

boolean isPrime(long n) {
    if (n < 2)
        return false;
    if (n == 2 || n == 3)
        return true;
    if (n % 2 == 0 || n % 3 == 0)
        return false;
    long sqrtN = (long) Math.sqrt(n) + 1;
    for (long i = 6L; i <= sqrtN; i += 6) {
        if (n % (i - 1) == 0 || n % (i + 1) == 0)
            return false;
    }
    return true;
}

}


Solution

  • The problem is that you are managing a list of Long objects and passing it in putExtra, which means you are invoking putExtra(String name, Serializable value). Then you try to get that value using getLongArray(), but you haven't put any long array extra, you see! To solve this, replace

    intent.putExtra(MainActivity.EXTRAARRAYID, primes.toArray());
    

    with

    long[] primesArray = new long[primes.size()];
    for (int i = 0; i < primes.size(); i++) {
        primesArray[i] = primes.get(i);
    }
    intent.putExtra(MainActivity.EXTRAARRAYID, primesArray);
    

    This will invoke the correct putExtra(String name, long[] value) method.