Reputation: 18763
I want to concatenate the data of two String arrays into third, but every time I use this code to concatenate the arrays my App stops working and shutdown:
ArrayList<String> SnoTitles3;
SnoTitles3 = new ArrayList<String>();
SnoTitles3.addAll(Arrays.asList(SnoTitles2));
SnoTitles3.addAll(Arrays.asList(SnoTitles1));
String [] concatedArgs = SnoTitles3.toArray(
new String[SnoTitles1.length +SnoTitles2.length]);
I have read in one of the Stackoverflow question that the Arrays SnoTitles1
and SnoTitles2
needed to be declared as final
in order to concatenate them into the third one, but I cannot use final
keyword with those two arrays because the size of these arrays is undefined initially but the size and the data inside these arrays is declared before the concatenation.
The data and the size of these two arrays are fetched from the XML, but everything is done before the concatenation part.
One more thing, the app works fine when I remove above lines of code/
Logcat output:
09-29 18:16:55.327: E/SocketStream(333): readFully was waiting for 403440 bytes, got 49152
09-29 18:16:55.327: E/SocketStream(333): readFully was waiting for 354288 bytes, got 49152
09-29 18:16:55.331: E/SocketStream(333): readFully was waiting for 305136 bytes, got 49152
09-29 18:16:55.331: E/SocketStream(333): readFully was waiting for 255984 bytes, got 16384
09-29 18:16:55.331: E/SocketStream(333): readFully was waiting for 239600 bytes, got 49152
09-29 18:16:55.331: E/SocketStream(333): readFully was waiting for 190448 bytes, got 49152
09-29 18:16:55.331: E/SocketStream(333): readFully was waiting for 141296 bytes, got 49152
09-29 18:16:55.331: E/SocketStream(333): readFully was waiting for 92144 bytes, got 5524
09-29 18:16:55.331: E/SocketStream(333): readFully was waiting for 86620 bytes, got 49152
09-29 18:16:55.331: E/SocketStream(333): readFully was waiting for 37468 bytes, got 32768
09-29 18:16:55.367: E/Trace(1028): error opening trace file: No such file or directory (2)
09-29 18:16:55.383: E/jdwp(1028): Failed writing handshake bytes: Broken pipe (-1 of 14)
09-29 18:16:55.447: E/AndroidRuntime(1028): FATAL EXCEPTION: main
09-29 18:16:55.447: E/AndroidRuntime(1028): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.news.securitynews/com.news.securitynews.MainActivity}: java.lang.NullPointerException
09-29 18:16:55.447: E/AndroidRuntime(1028): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
09-29 18:16:55.447: E/AndroidRuntime(1028): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
09-29 18:16:55.447: E/AndroidRuntime(1028): at android.app.ActivityThread.access$600(ActivityThread.java:130)
09-29 18:16:55.447: E/AndroidRuntime(1028): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
09-29 18:16:55.447: E/AndroidRuntime(1028): at android.os.Handler.dispatchMessage(Handler.java:99)
09-29 18:16:55.447: E/AndroidRuntime(1028): at android.os.Looper.loop(Looper.java:137)
09-29 18:16:55.447: E/AndroidRuntime(1028): at android.app.ActivityThread.main(ActivityThread.java:4745)
09-29 18:16:55.447: E/AndroidRuntime(1028): at java.lang.reflect.Method.invokeNative(Native Method)
09-29 18:16:55.447: E/AndroidRuntime(1028): at java.lang.reflect.Method.invoke(Method.java:511)
09-29 18:16:55.447: E/AndroidRuntime(1028): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
09-29 18:16:55.447: E/AndroidRuntime(1028): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-29 18:16:55.447: E/AndroidRuntime(1028): at dalvik.system.NativeStart.main(Native Method)
09-29 18:16:55.447: E/AndroidRuntime(1028): Caused by: java.lang.NullPointerException
09-29 18:16:55.447: E/AndroidRuntime(1028): at java.util.Arrays$ArrayList.<init>(Arrays.java:38)
09-29 18:16:55.447: E/AndroidRuntime(1028): at java.util.Arrays.asList(Arrays.java:154)
09-29 18:16:55.447: E/AndroidRuntime(1028): at com.news.securitynews.MainActivity.onCreate(MainActivity.java:61)
09-29 18:16:55.447: E/AndroidRuntime(1028): at android.app.Activity.performCreate(Activity.java:5008)
09-29 18:16:55.447: E/AndroidRuntime(1028): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
09-29 18:16:55.447: E/AndroidRuntime(1028): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
09-29 18:16:55.447: E/AndroidRuntime(1028): ... 11 more
09-29 18:16:55.467: E/SocketStream(333): readFully was waiting for 403440 bytes, got 49152
09-29 18:16:55.467: E/SocketStream(333): readFully was waiting for 354288 bytes, got 49152
09-29 18:16:55.467: E/SocketStream(333): readFully was waiting for 305136 bytes, got 49152
09-29 18:16:55.467: E/SocketStream(333): readFully was waiting for 255984 bytes, got 49152
09-29 18:16:55.467: E/SocketStream(333): readFully was waiting for 206832 bytes, got 196608
Update:
I have realized that my Program has few issues, the arrays SnoTitles1 and SnoTitles2 were initialized at the top of the class but the data is added inside them in a public mehtod, here is what I mean,
This is the MainActivity Class,
public class MainActivity extends ListActivity {
public String[] SnoTitles1;
public String[] SnoTitles2;
ArrayList<String> SnoTitles3;
String myString = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* here getBlogPostsTask.execute(); and getBlogPostsTask.execute1(); add the data inside the arrays using the method update_data1() and update_data2(), which are defined at the bottom.*/
GetJSONTitles getBlogPostsTask = new GetJSONTitles();
getBlogPostsTask.execute();
GetXMLTitles getBlogPostsTask1 = new GetXMLTitles();
getBlogPostsTask1.execute();
/* the values of both the Arrays SnoTitles1 and SnoTitles2 are updated when the above code is executed, so I tried to concatenate them below, */
SnoTitles3.addAll(Arrays.asList(SnoTitles2));
SnoTitles3.addAll(Arrays.asList(SnoTitles1));
String [] concatedArgs = SnoTitles3.toArray(new String[SnoTitles1.length+SnoTitles2.length]);
Here are the methods updated_data1 and update_data2 which modified the values of the Arrays,
public void update_data2(){
SnoTitles2 = new String[fetchedXMLTitles.getTitle().size()];
for (int i = 0; i < fetchedXMLTitles.getTitle().size(); i++) {
SnoTitles2[i] = fetchedXMLTitles.getTitle().get(i);
}
}
public void update_data1(){
SnoTitles1 = new String[fetchedXMLTitles.getTitle().size()];
for (int i = 0; i < fetchedXMLTitles.getTitle().size(); i++) {
SnoTitles2[i] = fetchedXMLTitles.getTitle().get(i);
}
}
}
both these methods are in the same class. I didn't shown the entire code because its too complex and its too difficult to explain it here.
The point is, If the Arrays SnoTitles1 and SnoTitles2 are modified inside the methods, then why cant I concatenate them ?
Upvotes: 3
Views: 2711
Reputation: 9655
-- Use System.arraycopy give you the best performance.
public static String[] concatArrays(String[] src1, String[] src2) {
if (src1 == null) {
throw new IllegalArgumentException("src1 is required.")
}
if (src2 == null) {
throw new IllegalArgumentException("src2 is required.")
}
String[] result = new String[src1.length + src2.length];
System.arraycopy(src1, 0, result, 0, src1.length);
System.arraycopy(src2, 0, result, src1.length, src2.length);
return result;
}
-- Back to your issue:
You will get NullPointerException if you have String array concatenation BEFORE both update_data1 and update_data2 get executed. Since these two methods called in different threads (I guess) so the best way to do is to have an COUNTER. Please see my solution:
// Total pending load is 2
AtomicInteger counter = new AtomicInteger(2);
public void update_data2(){
SnoTitles2 = new String[fetchedXMLTitles.getTitle().size()];
for (int i = 0; i < fetchedXMLTitles.getTitle().size(); i++) {
SnoTitles2[i] = fetchedXMLTitles.getTitle().get(i);
}
if (counter.decrementAndGet() == 0) {
// Perform array concatenation here
concatedArgs = concateString(SnoTitles1, SnoTitles2);
}
}
public void update_data1(){
SnoTitles1 = new String[fetchedXMLTitles.getTitle().size()];
for (int i = 0; i < fetchedXMLTitles.getTitle().size(); i++) {
SnoTitles1[i] = fetchedXMLTitles.getTitle().get(i);
}
if (counter.decrementAndGet() == 0) {
// Perform array concatenation here
concatedArgs = concateString(SnoTitles1, SnoTitles2);
}
}
Upvotes: 5