Android:无法连接两个数组

Suf*_*ori 3 java arrays android

我想将两个字符串数组的数据连接到第三个,但每次我使用此代码连接数组时,我的应用程序都会停止工作并关闭:

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]);
Run Code Online (Sandbox Code Playgroud)

我在 Stackoverflow 的一个问题中读到,数组SnoTitles1SnoTitles2需要声明为才能将final它们连接到第三个数组中,但我不能final对这两个数组使用关键字,因为这些数组的大小最初未定义,但大小和这些数组内的数据在串联之前声明。

这两个数组的数据和大小是从 XML 中获取的,但一切都在连接部分之前完成。

另一件事,当我删除上面的代码行时,应用程序运行正常/

Logcat 输出:

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 
Run Code Online (Sandbox Code Playgroud)

更新:

我意识到我的程序有几个问题,数组 SnoTitles1 和 SnoTitles2 是在类的顶部初始化的,但数据是通过公共方法添加到它们内部的,这就是我的意思,

这是 MainActivity 类,

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(); 
Run Code Online (Sandbox Code Playgroud)

/* 当上面的代码执行时,数组 SnoTitles1 和 SnoTitles2 的值都会更新,所以我尝试在下面连接它们,*/

SnoTitles3.addAll(Arrays.asList(SnoTitles2));
SnoTitles3.addAll(Arrays.asList(SnoTitles1));
String [] concatedArgs = SnoTitles3.toArray(new String[SnoTitles1.length+SnoTitles2.length]);
Run Code Online (Sandbox Code Playgroud)

下面是 update_data1 和 update_data2 方法,它们修改了数组的值,

    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); 
        }
    }


    }
Run Code Online (Sandbox Code Playgroud)

这两个方法都在同一个类中。我没有展示完整的代码,因为它太复杂并且很难在这里解释。

关键是,如果数组 SnoTitles1 和 SnoTitles2 在方法内部被修改,那么为什么我不能连接它们?

Loc*_*Loc 5

-- 使用System.arraycopy给你最好的性能。

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;
}
Run Code Online (Sandbox Code Playgroud)

——回到你的问题:

如果在执行 update_data1 和 update_data2 之前进行字符串数组连接,您将得到 NullPointerException。由于这两种方法在不同的线程中调用(我猜),所以最好的方法是有一个计数器。请看我的解决方案:

// 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);
    }
}
Run Code Online (Sandbox Code Playgroud)